@@ -25,6 +25,10 @@ func parseStatement(parser *statementParser, keyword, query string) (parsedState
2525 stmt = & parsedSetStatement {}
2626 } else if isResetStatementKeyword (keyword ) {
2727 stmt = & parsedResetStatement {}
28+ } else if isCreateKeyword (keyword ) && isCreateDatabase (parser , query ) {
29+ stmt = & parsedCreateDatabaseStatement {}
30+ } else if isDropKeyword (keyword ) && isDropDatabase (parser , query ) {
31+ stmt = & parsedDropDatabaseStatement {}
2832 } else {
2933 return nil , nil
3034 }
@@ -34,6 +38,28 @@ func parseStatement(parser *statementParser, keyword, query string) (parsedState
3438 return stmt , nil
3539}
3640
41+ func isCreateDatabase (parser * statementParser , query string ) bool {
42+ sp := & simpleParser {sql : []byte (query ), statementParser : parser }
43+ if _ , ok := sp .eatKeyword ("create" ); ! ok {
44+ return false
45+ }
46+ if _ , ok := sp .eatKeyword ("database" ); ! ok {
47+ return false
48+ }
49+ return true
50+ }
51+
52+ func isDropDatabase (parser * statementParser , query string ) bool {
53+ sp := & simpleParser {sql : []byte (query ), statementParser : parser }
54+ if _ , ok := sp .eatKeyword ("drop" ); ! ok {
55+ return false
56+ }
57+ if _ , ok := sp .eatKeyword ("database" ); ! ok {
58+ return false
59+ }
60+ return true
61+ }
62+
3763// SHOW [VARIABLE] [my_extension.]my_property
3864type parsedShowStatement struct {
3965 query string
@@ -250,3 +276,122 @@ func createEmptyRows(opts *ExecOptions) *rows {
250276 returnResultSetStats : opts .ReturnResultSetStats ,
251277 }
252278}
279+
280+ type parsedCreateDatabaseStatement struct {
281+ query string
282+ identifier identifier
283+ }
284+
285+ func (s * parsedCreateDatabaseStatement ) parse (parser * statementParser , query string ) error {
286+ // Parse a statement of the form
287+ // CREATE DATABASE <database-name>
288+ sp := & simpleParser {sql : []byte (query ), statementParser : parser }
289+ if _ , ok := sp .eatKeyword ("CREATE" ); ! ok {
290+ return status .Error (codes .InvalidArgument , "statement does not start with CREATE DATABASE" )
291+ }
292+ if _ , ok := sp .eatKeyword ("DATABASE" ); ! ok {
293+ return status .Error (codes .InvalidArgument , "statement does not start with CREATE DATABASE" )
294+ }
295+ identifier , err := sp .eatIdentifier ()
296+ if err != nil {
297+ return err
298+ }
299+ s .query = query
300+ s .identifier = identifier
301+ return nil
302+ }
303+
304+ func (s * parsedCreateDatabaseStatement ) execContext (ctx context.Context , c * conn , params string , opts * ExecOptions , args []driver.NamedValue ) (driver.Result , error ) {
305+ instance := fmt .Sprintf ("projects/%s/instances/%s" , c .connector .connectorConfig .Project , c .connector .connectorConfig .Instance )
306+ request := & databasepb.CreateDatabaseRequest {
307+ CreateStatement : s .query ,
308+ Parent : instance ,
309+ DatabaseDialect : c .parser .dialect ,
310+ }
311+ op , err := c .adminClient .CreateDatabase (ctx , request )
312+ if err != nil {
313+ return nil , err
314+ }
315+ if _ , err := op .Wait (ctx ); err != nil {
316+ return nil , err
317+ }
318+ return driver .ResultNoRows , nil
319+ }
320+
321+ func (s * parsedCreateDatabaseStatement ) queryContext (ctx context.Context , c * conn , params string , opts * ExecOptions , args []driver.NamedValue ) (driver.Rows , error ) {
322+ if _ , err := s .execContext (ctx , c , params , opts , args ); err != nil {
323+ return nil , err
324+ }
325+ return createEmptyRows (opts ), nil
326+ }
327+
328+ func (s * parsedCreateDatabaseStatement ) executableStatement (c * conn ) * executableClientSideStatement {
329+ return & executableClientSideStatement {
330+ conn : c ,
331+ query : s .query ,
332+ clientSideStatement : & clientSideStatement {
333+ Name : "CREATE DATABASE" ,
334+ execContext : s .execContext ,
335+ queryContext : s .queryContext ,
336+ },
337+ }
338+ }
339+
340+ type parsedDropDatabaseStatement struct {
341+ query string
342+ identifier identifier
343+ }
344+
345+ func (s * parsedDropDatabaseStatement ) parse (parser * statementParser , query string ) error {
346+ // Parse a statement of the form
347+ // DROP DATABASE <database-name>
348+ sp := & simpleParser {sql : []byte (query ), statementParser : parser }
349+ if _ , ok := sp .eatKeyword ("DROP" ); ! ok {
350+ return status .Error (codes .InvalidArgument , "statement does not start with DROP DATABASE" )
351+ }
352+ if _ , ok := sp .eatKeyword ("DATABASE" ); ! ok {
353+ return status .Error (codes .InvalidArgument , "statement does not start with DROP DATABASE" )
354+ }
355+ identifier , err := sp .eatIdentifier ()
356+ if err != nil {
357+ return err
358+ }
359+ s .query = query
360+ s .identifier = identifier
361+ return nil
362+ }
363+
364+ func (s * parsedDropDatabaseStatement ) execContext (ctx context.Context , c * conn , params string , opts * ExecOptions , args []driver.NamedValue ) (driver.Result , error ) {
365+ database := fmt .Sprintf (
366+ "projects/%s/instances/%s/databases/%s" ,
367+ c .connector .connectorConfig .Project ,
368+ c .connector .connectorConfig .Instance ,
369+ s .identifier .String ())
370+ request := & databasepb.DropDatabaseRequest {
371+ Database : database ,
372+ }
373+ err := c .adminClient .DropDatabase (ctx , request )
374+ if err != nil {
375+ return nil , err
376+ }
377+ return driver .ResultNoRows , nil
378+ }
379+
380+ func (s * parsedDropDatabaseStatement ) queryContext (ctx context.Context , c * conn , params string , opts * ExecOptions , args []driver.NamedValue ) (driver.Rows , error ) {
381+ if _ , err := s .execContext (ctx , c , params , opts , args ); err != nil {
382+ return nil , err
383+ }
384+ return createEmptyRows (opts ), nil
385+ }
386+
387+ func (s * parsedDropDatabaseStatement ) executableStatement (c * conn ) * executableClientSideStatement {
388+ return & executableClientSideStatement {
389+ conn : c ,
390+ query : s .query ,
391+ clientSideStatement : & clientSideStatement {
392+ Name : "DROP DATABASE" ,
393+ execContext : s .execContext ,
394+ queryContext : s .queryContext ,
395+ },
396+ }
397+ }
0 commit comments