From 47c5be1038c47b7a4f1c88a1f4a75bbc51bb7764 Mon Sep 17 00:00:00 2001 From: Patrick O'brien Date: Wed, 24 Feb 2016 18:53:34 +1000 Subject: [PATCH] Removed unused test files, added comments to cmds * Added comments to all cmds files * Removed unused test files * Removed unimplemented command 'update' --- cmds/all.go | 2 ++ cmds/config.go | 2 ++ cmds/delete.go | 5 ++++ cmds/insert.go | 13 +++++++--- cmds/select.go | 9 +++++++ cmds/select_test.go | 1 - cmds/shared.go | 21 +++++++++++++++- cmds/sqlboiler.go | 60 +++++++++++++++++++++++++++++++++++++++++--- cmds/structs.go | 5 ++++ cmds/structs_test.go | 15 ----------- cmds/update.go | 29 --------------------- 11 files changed, 109 insertions(+), 53 deletions(-) delete mode 100644 cmds/select_test.go delete mode 100644 cmds/structs_test.go delete mode 100644 cmds/update.go diff --git a/cmds/all.go b/cmds/all.go index 970670a..6c4aa2c 100644 --- a/cmds/all.go +++ b/cmds/all.go @@ -2,6 +2,7 @@ package cmds import "github.com/spf13/cobra" +// init the "all" command func init() { SQLBoiler.AddCommand(allCmd) allCmd.Run = allRun @@ -12,6 +13,7 @@ var allCmd = &cobra.Command{ Short: "Generate all templates from table definitions", } +// allRun executes every sqlboiler command, starting with structs func allRun(cmd *cobra.Command, args []string) { err := outHandler(generateStructs()) if err != nil { diff --git a/cmds/config.go b/cmds/config.go index b16cfc0..9e8d3f7 100644 --- a/cmds/config.go +++ b/cmds/config.go @@ -7,6 +7,7 @@ import ( "github.com/BurntSushi/toml" ) +// cfg holds the configuration file data from config.toml var cfg = struct { Postgres struct { User string `toml:"user"` @@ -17,6 +18,7 @@ var cfg = struct { } `toml:"postgres"` }{} +// init reads the config.toml configuration file into the cfg variable func init() { _, err := toml.DecodeFile("config.toml", &cfg) if err == nil { diff --git a/cmds/delete.go b/cmds/delete.go index 4b71054..8346f10 100644 --- a/cmds/delete.go +++ b/cmds/delete.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/cobra" ) +// init the "delete" command func init() { SQLBoiler.AddCommand(deleteCmd) deleteCmd.Run = deleteRun @@ -16,6 +17,8 @@ var deleteCmd = &cobra.Command{ Short: "Generate delete statement helpers from table definitions", } +// deleteRun executes the delete command, and generates the delete statement +// boilerplate from the template file. func deleteRun(cmd *cobra.Command, args []string) { err := outHandler(generateDeletes()) if err != nil { @@ -23,6 +26,8 @@ func deleteRun(cmd *cobra.Command, args []string) { } } +// generateDeletes returns a slice of each template execution result. +// Each of these results holds a delete statement generated from the delete template. func generateDeletes() [][]byte { t, err := template.New("delete.tpl").Funcs(template.FuncMap{ "makeGoColName": makeGoColName, diff --git a/cmds/insert.go b/cmds/insert.go index e69485a..15d2728 100644 --- a/cmds/insert.go +++ b/cmds/insert.go @@ -8,6 +8,7 @@ import ( "github.com/spf13/cobra" ) +// init the "insert" command func init() { SQLBoiler.AddCommand(insertCmd) insertCmd.Run = insertRun @@ -18,6 +19,8 @@ var insertCmd = &cobra.Command{ Short: "Generate insert statement helpers from table definitions", } +// insertRun executes the insert command, and generates the insert statement +// boilerplate from the template file. func insertRun(cmd *cobra.Command, args []string) { err := outHandler(generateInserts()) if err != nil { @@ -25,6 +28,8 @@ func insertRun(cmd *cobra.Command, args []string) { } } +// generateInserts returns a slice of each template execution result. +// Each of these results holds an insert statement generated from the insert template. func generateInserts() [][]byte { t, err := template.New("insert.tpl").Funcs(template.FuncMap{ "makeGoColName": makeGoColName, @@ -45,8 +50,8 @@ func generateInserts() [][]byte { return outputs } -// makeGoInsertParamNames takes a [][]DBData and returns a comma seperated -// list of parameter names for the insert statement +// makeGoInsertParamNames takes a []DBTable and returns a comma seperated +// list of parameter names for the insert statement template. func makeGoInsertParamNames(data []dbdrivers.DBTable) string { var paramNames string for i := 0; i < len(data); i++ { @@ -58,8 +63,8 @@ func makeGoInsertParamNames(data []dbdrivers.DBTable) string { return paramNames } -// makeGoInsertParamFlags takes a [][]DBData and returns a comma seperated -// list of parameter flags for the insert statement +// makeGoInsertParamFlags takes a []DBTable and returns a comma seperated +// list of parameter flags for the insert statement template. func makeGoInsertParamFlags(data []dbdrivers.DBTable) string { var paramFlags string for i := 0; i < len(data); i++ { diff --git a/cmds/select.go b/cmds/select.go index d11defb..16b30e9 100644 --- a/cmds/select.go +++ b/cmds/select.go @@ -8,6 +8,7 @@ import ( "github.com/spf13/cobra" ) +// init the "select" command func init() { SQLBoiler.AddCommand(selectCmd) selectCmd.Run = selectRun @@ -18,6 +19,8 @@ var selectCmd = &cobra.Command{ Short: "Generate select statement helpers from table definitions", } +// selectRun executes the select command, and generates the select statement +// boilerplate from the select file. func selectRun(cmd *cobra.Command, args []string) { err := outHandler(generateSelects()) if err != nil { @@ -25,6 +28,8 @@ func selectRun(cmd *cobra.Command, args []string) { } } +// generateSelects returns a slice of each template execution result. +// Each of these results holds a select statement generated from the select template. func generateSelects() [][]byte { t, err := template.New("select.tpl").Funcs(template.FuncMap{ "makeGoColName": makeGoColName, @@ -44,6 +49,10 @@ func generateSelects() [][]byte { return outputs } +// makeSelectParamNames takes a []DBTable and returns a comma seperated +// list of parameter names with for the select statement template. +// It also uses the table name to generate the "AS" part of the statement, for +// example: var_name AS table_name_var_name, ... func makeSelectParamNames(tableName string, data []dbdrivers.DBTable) string { var paramNames string for i := 0; i < len(data); i++ { diff --git a/cmds/select_test.go b/cmds/select_test.go deleted file mode 100644 index ce2fc16..0000000 --- a/cmds/select_test.go +++ /dev/null @@ -1 +0,0 @@ -package cmds diff --git a/cmds/shared.go b/cmds/shared.go index 405ec5a..74471c4 100644 --- a/cmds/shared.go +++ b/cmds/shared.go @@ -11,16 +11,20 @@ import ( "github.com/pobri19/sqlboiler/dbdrivers" ) +// tplData is used to pass data to the template type tplData struct { TableName string TableData []dbdrivers.DBTable } +// errorQuit displays an error message and then exits the application. func errorQuit(err error) { fmt.Println(fmt.Sprintf("Error: %s\n---\n\nRun 'sqlboiler --help' for usage.", err)) os.Exit(-1) } +// processTemplate takes a template and returns a slice of byte slices. +// Each byte slice in the slice of bytes is the output of the template execution. func processTemplate(t *template.Template) ([][]byte, error) { var outputs [][]byte for i := 0; i < len(cmdData.TablesInfo); i++ { @@ -46,9 +50,12 @@ func processTemplate(t *template.Template) ([][]byte, error) { } +// outHandler loops over the slice of byte slices, outputting them to either +// the OutFile if it is specified with a flag, or to Stdout if no flag is specified. func outHandler(data [][]byte) error { nl := []byte{'\n'} + // Use stdout if no outfile is specified var out *os.File if cmdData.OutFile == nil { out = os.Stdout @@ -68,6 +75,10 @@ func outHandler(data [][]byte) error { return nil } +// makeGoColName takes a column name in the format of "column_name" and converts +// it into a go styled object variable name of "ColumnName". +// makeGoColName also fully uppercases "ID" components of names, for example +// "column_name_id" to "ColumnNameID". func makeGoColName(name string) string { s := strings.Split(name, "_") @@ -82,11 +93,16 @@ func makeGoColName(name string) string { return strings.Join(s, "") } +// makeGoVarName takes a variable name in the format of "var_name" and converts +// it into a go styled variable name of "varName". +// makeGoVarName also fully uppercases "ID" components of names, for example +// "var_name_id" to "varNameID". func makeGoVarName(name string) string { s := strings.Split(name, "_") for i := 0; i < len(s); i++ { - if s[i] == "id" { + // Only uppercase if not a single word variable + if s[i] == "id" && i > 0 { s[i] = "ID" continue } @@ -102,6 +118,9 @@ func makeGoVarName(name string) string { return strings.Join(s, "") } +// makeDBColName takes a table name in the format of "table_name" and a +// column name in the format of "column_name" and returns a name used in the +// `db:""` component of an object in the format of "table_name_column_name" func makeDBColName(tableName, colName string) string { return tableName + "_" + colName } diff --git a/cmds/sqlboiler.go b/cmds/sqlboiler.go index ad7506f..e180019 100644 --- a/cmds/sqlboiler.go +++ b/cmds/sqlboiler.go @@ -9,6 +9,10 @@ import ( "github.com/spf13/cobra" ) +// CmdData holds the table schema a slice of (column name, column type) slices. +// It also holds a slice of all of the table names sqlboiler is generating against, +// the database driver chosen by the driver flag at runtime, and a pointer to the +// output file, if one is specified with a flag. type CmdData struct { TablesInfo [][]dbdrivers.DBTable TableNames []string @@ -16,8 +20,14 @@ type CmdData struct { OutFile *os.File } +// cmdData is used globally by all commands to access the table schema data, +// the database driver and the output file. cmdData is initialized by +// the root SQLBoiler cobra command at run time, before other commands execute. var cmdData *CmdData +// init initializes the sqlboiler flags, such as driver, table, and output file. +// It also sets the global preRun hook and postRun hook. Every command will execute +// these hooks before and after running to initialize the shared state. func init() { SQLBoiler.PersistentFlags().StringP("driver", "d", "", "The name of the driver in your config.toml") SQLBoiler.PersistentFlags().StringP("table", "t", "", "A comma seperated list of table names") @@ -26,6 +36,7 @@ func init() { SQLBoiler.PersistentPostRun = sqlBoilerPostRun } +// SQLBoiler is the root app command var SQLBoiler = &cobra.Command{ Use: "sqlboiler", Short: "SQL Boiler generates boilerplate structs and statements", @@ -33,15 +44,44 @@ var SQLBoiler = &cobra.Command{ `Complete documentation is available at http://github.com/pobri19/sqlboiler`, } +// sqlBoilerPostRun cleans up the output file and database connection once +// all commands are finished running. func sqlBoilerPostRun(cmd *cobra.Command, args []string) { cmdData.OutFile.Close() cmdData.DBDriver.Close() } +// sqlBoilerPreRun executes before all commands start running. Its job is to +// initialize the shared state object (cmdData). Initialization tasks include +// assigning the database driver based off the driver flag and opening the database connection, +// retrieving a list of all the tables in the database (if specific tables are not provided +// via a flag), building the table schema for use in the templates, and opening the output file +// handle if one is specified with a flag. func sqlBoilerPreRun(cmd *cobra.Command, args []string) { var err error cmdData = &CmdData{} + // Initialize the cmdData.DBDriver + initDBDriver() + + // Connect to the driver database + if err = cmdData.DBDriver.Open(); err != nil { + errorQuit(err) + } + + // Initialize the cmdData.TableNames + initTableNames() + + // Initialize the cmdData.TablesInfo + initTablesInfo() + + // Initialize the cmdData.OutFile + initOutFile() +} + +// initDBDriver attempts to set the cmdData DBDriver based off the passed in +// driver flag value. If an invalid flag string is provided the program will exit. +func initDBDriver() { // Retrieve driver flag driverName := SQLBoiler.PersistentFlags().Lookup("driver").Value.String() if driverName == "" { @@ -60,11 +100,15 @@ func sqlBoilerPreRun(cmd *cobra.Command, args []string) { ) } - // Connect to the driver database - if err = cmdData.DBDriver.Open(); err != nil { - errorQuit(err) + if cmdData.DBDriver == nil { + errorQuit(errors.New("An invalid driver name was provided")) } +} +// initTableNames will create a string slice out of the passed in table flag value +// if one is provided. If no flag is provided, it will attempt to connect to the +// database to retrieve all "public" table names, and build a slice out of that result. +func initTableNames() { // Retrieve the list of tables tn := SQLBoiler.PersistentFlags().Lookup("table").Value.String() @@ -78,6 +122,7 @@ func sqlBoilerPreRun(cmd *cobra.Command, args []string) { // If no table names are provided attempt to process all tables in database if len(cmdData.TableNames) == 0 { // get all table names + var err error cmdData.TableNames, err = cmdData.DBDriver.GetAllTableNames() if err != nil { errorQuit(err) @@ -87,7 +132,11 @@ func sqlBoilerPreRun(cmd *cobra.Command, args []string) { errorQuit(errors.New("No tables found in database, migrate some tables first")) } } +} +// initTablesInfo builds a description of each table (column name, column type) +// and assigns it to cmdData.TablesInfo, the slice of dbdrivers.DBTable slices. +func initTablesInfo() { // loop over table Names and build TablesInfo for i := 0; i < len(cmdData.TableNames); i++ { tInfo, err := cmdData.DBDriver.GetTableInfo(cmdData.TableNames[i]) @@ -97,7 +146,12 @@ func sqlBoilerPreRun(cmd *cobra.Command, args []string) { cmdData.TablesInfo = append(cmdData.TablesInfo, tInfo) } +} +// initOutFile opens a file handle to the file name specified by the out flag. +// If no file name is provided, out will remain nil and future output will be +// piped to Stdout instead of to a file. +func initOutFile() { // open the out file filehandle outf := SQLBoiler.PersistentFlags().Lookup("out").Value.String() if outf != "" { diff --git a/cmds/structs.go b/cmds/structs.go index 57bd591..91aa01c 100644 --- a/cmds/structs.go +++ b/cmds/structs.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/cobra" ) +// init the "struct" command func init() { SQLBoiler.AddCommand(structCmd) structCmd.Run = structRun @@ -16,6 +17,8 @@ var structCmd = &cobra.Command{ Short: "Generate structs from table definitions", } +// deleteRun executes the struct command, and generates the struct definitions +// boilerplate from the template file. func structRun(cmd *cobra.Command, args []string) { err := outHandler(generateStructs()) if err != nil { @@ -23,6 +26,8 @@ func structRun(cmd *cobra.Command, args []string) { } } +// generateStructs returns a slice of each template execution result. +// Each of these results holds a struct definition generated from the struct template. func generateStructs() [][]byte { t, err := template.New("struct.tpl").Funcs(template.FuncMap{ "makeGoColName": makeGoColName, diff --git a/cmds/structs_test.go b/cmds/structs_test.go deleted file mode 100644 index 17b5119..0000000 --- a/cmds/structs_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package cmds - -import "testing" - -func testVerifyStructArgs(t *testing.T) { - err := verifyStructArgs([]string{}) - if err == nil { - t.Error("Expected an error") - } - - err = verifyStructArgs([]string{"hello"}) - if err != nil { - t.Errorf("Expected error nil, got: %s", err) - } -} diff --git a/cmds/update.go b/cmds/update.go deleted file mode 100644 index 8002d5b..0000000 --- a/cmds/update.go +++ /dev/null @@ -1,29 +0,0 @@ -package cmds - -import ( - "os" - - "github.com/spf13/cobra" -) - -func init() { - SQLBoiler.AddCommand(updateCmd) - updateCmd.Run = updateRun -} - -var updateCmd = &cobra.Command{ - Use: "update", - Short: "Generate update statement helpers from table definitions", -} - -func updateRun(cmd *cobra.Command, args []string) { - out := generateUpdates() - - for _, v := range out { - os.Stdout.Write(v) - } -} - -func generateUpdates() [][]byte { - return [][]byte{} -}