@@ -19,6 +19,7 @@ import (
1919 "context"
2020 "database/sql"
2121 "errors"
22+ "fmt"
2223 "io"
2324 "text/template"
2425 "time"
@@ -34,17 +35,18 @@ Data struct to configure dump behavior
3435 LockTables: Lock all tables for the duration of the dump
3536*/
3637type Data struct {
37- Out io.Writer
38- Connection * sql.DB
39- IgnoreTables []string
40- MaxAllowedPacket int
41- LockTables bool
42- Schema string
43- Compact bool
44- Host string
45- SuppressUseDatabase bool
46- Charset string
47- Collation string
38+ Out io.Writer
39+ Connection * sql.DB
40+ IgnoreTables []string
41+ MaxAllowedPacket int
42+ LockTables bool
43+ Schema string
44+ Compact bool
45+ TriggersAndFunctions bool
46+ Host string
47+ SuppressUseDatabase bool
48+ Charset string
49+ Collation string
4850
4951 tx * sql.Tx
5052 headerTmpl * template.Template
@@ -186,6 +188,19 @@ func (data *Data) Dump() error {
186188 return err
187189 }
188190 }
191+
192+ // Dump triggers and functions
193+ if data .TriggersAndFunctions {
194+ if err := data .dumpTriggers (); err != nil {
195+ return err
196+ }
197+
198+ // Dump procedures and functions
199+ if err := data .dumpProceduresAndFunctions (); err != nil {
200+ return err
201+ }
202+ }
203+
189204 if data .err != nil {
190205 return data .err
191206 }
@@ -328,6 +343,68 @@ func (data *Data) isIgnoredTable(name string) bool {
328343 return false
329344}
330345
346+ // dumpTriggers dump the triggers for the current schema
347+ func (data * Data ) dumpTriggers () error {
348+ rows , err := data .tx .Query ("SHOW TRIGGERS FROM `" + data .Schema + "`" )
349+ if err != nil {
350+ return err
351+ }
352+ defer rows .Close ()
353+
354+ for rows .Next () {
355+ var triggerName , event , timing , statement , sqlMode , definer , table , charset sql.NullString
356+ var created sql.NullTime
357+ if err := rows .Scan (& triggerName , & event , & timing , & statement , & sqlMode , & definer , & table , & created , & charset ); err != nil {
358+ return err
359+ }
360+ if ! triggerName .Valid || ! statement .Valid {
361+ continue
362+ }
363+ _ , err := data .Out .Write ([]byte (fmt .Sprintf ("CREATE TRIGGER `%s` %s %s ON `%s` FOR EACH ROW %s;\n " ,
364+ triggerName .String , timing .String , event .String , table .String , statement .String )))
365+ if err != nil {
366+ return err
367+ }
368+ }
369+ return nil
370+ }
371+
372+ // dumpProceduresAndFunctions dump the procedures and functions for the current schema
373+ func (data * Data ) dumpProceduresAndFunctions () error {
374+ queries := []string {
375+ "SHOW PROCEDURE STATUS WHERE Db = '" + data .Schema + "'" ,
376+ "SHOW FUNCTION STATUS WHERE Db = '" + data .Schema + "'" ,
377+ }
378+ for _ , query := range queries {
379+ rows , err := data .tx .Query (query )
380+ if err != nil {
381+ return err
382+ }
383+ defer rows .Close ()
384+
385+ for rows .Next () {
386+ var name , typeDef , otherFields sql.NullString
387+ if err := rows .Scan (& name , & typeDef , & otherFields ); err != nil {
388+ return err
389+ }
390+ if name .Valid && typeDef .Valid {
391+ createQuery := fmt .Sprintf ("SHOW CREATE %s `%s`" , typeDef .String , name .String )
392+ var createStmt sql.NullString
393+ if err := data .tx .QueryRow (createQuery ).Scan (& createStmt ); err != nil {
394+ return err
395+ }
396+ if createStmt .Valid {
397+ _ , err := data .Out .Write ([]byte (createStmt .String + "\n " ))
398+ if err != nil {
399+ return err
400+ }
401+ }
402+ }
403+ }
404+ }
405+ return nil
406+ }
407+
331408func (meta * metaData ) updateMetadata (data * Data ) (err error ) {
332409 var serverVersion sql.NullString
333410 err = data .tx .QueryRow ("SELECT version()" ).Scan (& serverVersion )
0 commit comments