script icon indicating copy to clipboard operation
script copied to clipboard

Question: Prepend a string to a file within a pipeline?

Open Michael-F-Ellis opened this issue 3 years ago • 5 comments

First, thanks for creating and maintaining this package! It's something I've wished for repeatedly since discovering Go a few years ago AND the implementation is really clean.

Upon discovering script yesterday, I put it to work in query handler for sqlite.

// Query executes a SQL query contained in a file at qrypath against the sqlite3
// db file located at dbpath.  The result is returned as a string and err will
// be non-nil if an error is encountered.
// You may pass zero or more sqlite3 special commands in dotcmd. These are
// typically used to change the output format, e.g. ".mode json" but other
// special commands may be useful.  Sqlite3 currently recognizes more than 60
// dot commands. See https://www.sqlite.org/cli.html for more info.
func Query(qrypath string, dbpath string, dotcmd ...string) (result string, err error) {
	qrybytes, err := ioutil.ReadFile(qrypath)
	if err != nil {
		return
	}
	qry := strings.Join(dotcmd, "\n") + "\n" + string(qrybytes)
	cmd := fmt.Sprintf("sqlite3 %s", dbpath)
	result, err = script.Echo(qry).Exec(cmd).String()
	return
}

So is there any way to construct a pipeline that would catenate the joined dotcmd lines and the content of the sql file (qrypath) before passing it to Exec?

Michael-F-Ellis avatar Jul 03 '22 13:07 Michael-F-Ellis

You're welcome @Michael-F-Ellis! This looks like an interesting application.

I don't think we can do this in one pipeline at the moment; script.Slice will produce a pipe containing your slice of dotcmd strings, one per line, and script.File will produce a pipe containing the contents of your query file. But currently we'd have to extract these to strings and then write another pipeline to send them to the command.

Can you suggest a neat syntax for doing this operation all in one pipeline? If so, I'd certainly consider including it in the library.

bitfield avatar Jul 04 '22 08:07 bitfield

Is it feasible to add an AppendFromFile function? It would have to behave something like sponge i.e., soak up all the input from the pipeline and then emit the input followed by the file contents. That would allow writing the body of my Query() func in 3 succinct lines.

dots := strings.Join(dotcmd, "\n") + "\n"
cmd := fmt.Sprintf("sqlite3 %s", dbpath)
result, err = script.Echo(dots).AppendFromFile(qrypath).Exec(cmd).String()

Michael-F-Ellis avatar Jul 05 '22 13:07 Michael-F-Ellis

That sounds good!

bitfield avatar Jul 05 '22 15:07 bitfield