@@ -36,6 +36,10 @@ type Formatter interface {
3636 AddMessage (string )
3737 // AddError is called for each error encountered during batch execution
3838 AddError (err error )
39+ // XmlMode enables or disables XML rendering mode
40+ XmlMode (enable bool )
41+ // IsXmlMode returns whether XML mode is enabled
42+ IsXmlMode () bool
3943}
4044
4145// ControlCharacterBehavior specifies the text handling required for control characters in the output
@@ -77,6 +81,7 @@ type sqlCmdFormatterType struct {
7781 format string
7882 maxColNameLen int
7983 colorizer color.Colorizer
84+ xml bool
8085}
8186
8287// NewSQLCmdDefaultFormatter returns a Formatter that mimics the original ODBC-based sqlcmd formatter
@@ -119,7 +124,7 @@ func (f *sqlCmdFormatterType) writeOut(s string, t color.TextType) {
119124 }
120125}
121126
122- // Stores the settings to use for processing the current batch
127+ // BeginBatch stores the settings to use for processing the current batch
123128// TODO: add a third io.Writer for messages when we add -r support
124129func (f * sqlCmdFormatterType ) BeginBatch (_ string , vars * Variables , out io.Writer , err io.Writer ) {
125130 f .out = out
@@ -138,17 +143,19 @@ func (f *sqlCmdFormatterType) EndBatch() {
138143func (f * sqlCmdFormatterType ) BeginResultSet (cols []* sql.ColumnType ) {
139144 f .rowcount = 0
140145 f .columnDetails , f .maxColNameLen = calcColumnDetails (cols , f .vars .MaxFixedColumnWidth (), f .vars .MaxVarColumnWidth ())
141- if f .vars .RowsBetweenHeaders () > - 1 && f .format == "horizontal" {
146+ if f .vars .RowsBetweenHeaders () > - 1 && f .format == "horizontal" && ! f . xml {
142147 f .printColumnHeadings ()
143148 }
144149}
145150
146- // Writes a blank line to the designated output writer
151+ // EndResultSet writes a blank line to the designated output writer
147152func (f * sqlCmdFormatterType ) EndResultSet () {
148- f .writeOut (SqlcmdEol , color .TextTypeNormal )
153+ if ! f .xml {
154+ f .writeOut (SqlcmdEol , color .TextTypeNormal )
155+ }
149156}
150157
151- // Writes the current row to the designated output writer
158+ // AddRow writes the current row to the designated output writer
152159func (f * sqlCmdFormatterType ) AddRow (row * sql.Rows ) string {
153160 retval := ""
154161 values , err := f .scanRow (row )
@@ -157,7 +164,9 @@ func (f *sqlCmdFormatterType) AddRow(row *sql.Rows) string {
157164 return retval
158165 }
159166 retval = values [0 ]
160- if f .format == "horizontal" {
167+ if f .xml {
168+ f .printColumnValue (retval , 0 )
169+ } else if f .format == "horizontal" {
161170 // values are the full values, look at the displaywidth of each column and truncate accordingly
162171 for i , v := range values {
163172 if i > 0 {
@@ -176,7 +185,6 @@ func (f *sqlCmdFormatterType) AddRow(row *sql.Rows) string {
176185 }
177186 f .writeOut (SqlcmdEol , color .TextTypeNormal )
178187 return retval
179-
180188}
181189
182190func (f * sqlCmdFormatterType ) addVerticalRow (values []string ) {
@@ -193,12 +201,14 @@ func (f *sqlCmdFormatterType) addVerticalRow(values []string) {
193201 }
194202}
195203
196- // Writes a non-error message to the designated message writer
204+ // AddMessage writes a non-error message to the designated message writer
197205func (f * sqlCmdFormatterType ) AddMessage (msg string ) {
198- f .mustWriteOut (msg + SqlcmdEol , color .TextTypeWarning )
206+ if ! f .xml {
207+ f .mustWriteOut (msg + SqlcmdEol , color .TextTypeWarning )
208+ }
199209}
200210
201- // Writes an error to the designated err Writer
211+ // AddError writes an error to the designated err Writer
202212func (f * sqlCmdFormatterType ) AddError (err error ) {
203213 print := true
204214 b := new (strings.Builder )
@@ -217,6 +227,16 @@ func (f *sqlCmdFormatterType) AddError(err error) {
217227 }
218228}
219229
230+ // XmlMode enables or disables XML mode
231+ func (f * sqlCmdFormatterType ) XmlMode (enable bool ) {
232+ f .xml = enable
233+ }
234+
235+ // IsXmlMode returns whether XML mode is enabled
236+ func (f * sqlCmdFormatterType ) IsXmlMode () bool {
237+ return f .xml
238+ }
239+
220240// Prints column headings based on columnDetail, variables, and command line arguments
221241func (f * sqlCmdFormatterType ) printColumnHeadings () {
222242 names := new (strings.Builder )
@@ -535,7 +555,7 @@ func (f *sqlCmdFormatterType) printColumnValue(val string, col int) {
535555
536556 s .WriteString (val )
537557 r := []rune (val )
538- if f .format == "horizontal" {
558+ if ! f . xml && f .format == "horizontal" {
539559 if ! f .removeTrailingSpaces {
540560 if f .vars .MaxVarColumnWidth () != 0 || ! isLargeVariableType (& c .col ) {
541561 padding := c .displayWidth - min64 (c .displayWidth , int64 (len (r )))
@@ -551,11 +571,15 @@ func (f *sqlCmdFormatterType) printColumnValue(val string, col int) {
551571
552572 r = []rune (s .String ())
553573 }
554- if c .displayWidth > 0 && int64 (len (r )) > c .displayWidth {
574+ if ! f . xml && ( c .displayWidth > 0 && int64 (len (r )) > c .displayWidth ) {
555575 s .Reset ()
556576 s .WriteString (string (r [:c .displayWidth ]))
557577 }
558- f .writeOut (s .String (), color .TextTypeCell )
578+ clr := color .TextTypeCell
579+ if f .xml {
580+ clr = color .TextTypeXml
581+ }
582+ f .writeOut (s .String (), clr )
559583}
560584
561585func (f * sqlCmdFormatterType ) mustWriteOut (s string , t color.TextType ) {
0 commit comments