Command StdinPipe closes too soon - postgresql

I've been trying to call pg_restore using exec.Command and feed StdinPipe with data from database dump file, it works with small files under 1Mb but it fails for bigger dumps with the write |1: broken pipe error. I also tried to scan line by line and write to pipe but it resulted in the same error and running like cmd.Run() in separate goroutine didn't help either.
Go: 1.14
OS: macOS
cmd := exec.Command("pg_restore", "--clean", "-n public", "--dbname=DB_URI")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
pw, err := cmd.StdinPipe()
defer pw.Close()
...
done := make(chan struct{})
errCh := make(chan error)
file, err := os.Open("dumpfile")
defer file.Close()
if err := cmd.Start(); err != nil {
return err
}
_, err = io.Copy(pw, file)
What am I doing wrong or how to keep pipe open?

When using cat instead of pg_restore, your code works.
When using head -10, on the other hand, I hit the same error as you, which is actually expected.
Since you are starting your cmd in async mode, if pg_restore halts before consuming all of its STDIN, io.Copy will hit this kind of error if it tries to write on a closed pipe.
Check the state of your pg_restore command (final return code, content printed on its STDERR, logs ...) to see if there is an actual error.
You can treat this error as a normal indication that you shouldn't feed input to this command anymore.

including cmd.Wait() should solve your problem, like it says int one of your comments.

With the help of my colleague we found that command arguments were malformed, since Go directly uses syscalls each argument of a program must be separate so here
-n public was leading to the issue
"pg_restore", "--clean", "-n public", "--dbname=DB_URI"
and the fix quite clear as well – split them -n, public
"pg_restore", "--clean", "-n", "public", "--dbname=DB_URI"

Related

Linter Issue with Go-MongoDB Collections Find Query

My Go code has several statements of the sort:
cursor, err := collection.Find(context.TODO(), bson.D{{}})
and they work as expected but the linter complains when executing:
golangci-lint run ./... && ginkgo -r -cover
The linter displays the following error:
missing type in composite literal (typecheck)
cursor, err := collection.Find(context.TODO(), bson.D{{}})
Even when I provide key/value pairs the linter still complains. How can I solve this? Thanks.
This happens when the go compiler doesn't recognize the bson.D type. Check if you have initialized go modules.
go mod init
Either ways, do a tidy
go mod tidy
If should print the following output
go: finding module for package gopkg.in/mgo.v2/bson
go: finding module for package go.mongodb.org/mongo-driver/mongo
go: finding module for package go.mongodb.org/mongo-driver/mongo/options
...
Run the linter.

how to open new instance of acrobat

I'm using windows 10 task view and need to open different instances of excel word and acrobat.
I can't seem to get acrobat working. I get error: 0x800401F3 - Invalid class string on the AcroApp := ComObjCreate("AcroExch.App") line.
Any suggestions?
^+n::
oWord := ComObjCreate("Word.Application")
oWord.Documents.Add
oWord.Visible := 1
oWord.Activate
xlApp := ComObjCreate("Excel.Application")
xlApp.Visible := true
xlApp.Workbooks.Add()
xlApp := ""
run notepad
run chrome
AcroApp := ComObjCreate("AcroExch.App"); Error when running
AcroApp.Visible := true
AcroApp.Open
return
While the COM approach seems cool, it seems really unnecessary.
I don't have Acrobat, but a quick Google search tells me they have a command line option to open a new instance, as I suspected (documented here).
So, a quick little run command should do the trick:
Run, % """C:\Path\To\Acrobat.exe"" /n"
Also, maybe this is why your COM approach didn't work?

Does BaseX support running a basex script file (.bxs) with the jobs module or a combination of query with proc module and jobs module?

This has been a thorn in my side and I'm wondering if I'm missing something simple or not. I need to run .bxs scripts from the jobs scheduler.
I tried to start a service with a .bxs script file from the jobs module but it does not run. It registers as a service but the script does not run.
let $home := Q{org.basex.util.Prop}HOMEDIR()
let $job := $home || 'webapp/sync/update_jira.bxs'
let $job2 := $home || 'webapp/sync/update_commit_data.bxs'
return (jobs:eval(xs:anyURI($job), (), map { 'id':'update_jira_job', 'start':'14:54:02', 'interval':'P1D', 'service': true(), 'log': 'update_jira_job'}),
jobs:eval(xs:anyURI($job2), (), map { 'id':'update_commit_data', 'start':'15:03:02', 'interval':'P1D', 'service': true(), 'log': 'update_commit_data'}))
I also tried to run a query that executes the command line to run the scripts for example within the update_jira.xq there is a line proc:execute('basex update_jira.bxs') from an initial query that looks something like this...
let $home := Q{org.basex.util.Prop}HOMEDIR()
let $job := $home || '/srv/webapp/sync/update_jira.xq'
let $job2 := $home || '/src/webapp/sync/update_commit_data.xq'
return (jobs:eval(xs:anyURI($job), (), map { 'id':'update_jira_job', 'start':'14:54:02', 'interval':'P1D', 'service': true(), 'log': 'update_jira_job'}),
jobs:eval(xs:anyURI($job2), (), map { 'id':'update_commit_data', 'start':'15:03:02', 'interval':'P1D', 'service': true(), 'log': 'update_commit_data'}))
When this ran as a service, the database did not update as expected and I got this output in the log:
22:47:02.001 JOB:update_commit_data admin OK 0.30 update_commit_data
22:41:00.000 JOB:update_jira_job admin ERROR 0.00 update_jira_job; Unexpected end of query: '0'.
But that is strange because when I ran the query itself -- that starts the service with jobs:eval -- then it actually ran ok when I ran the query for the first time.
16:42:52.257 10.244.144.142:57444 admin 200 221563.70 [GET] /rest?run=sync/update_jira.bxs
16:49:39.862 10.244.144.142:57591 admin 200 101413.21 [GET] /rest?run=sync/update_commit_data.bxs
This is my latest attempt where the query runs initially but then doesn't seem to execute as a service interval. I added the base-uri as the path to the query and I hope that's the right way to do that.
let $home := Q{org.basex.util.Prop}HOMEDIR()
return jobs:eval(proc:execute('/usr/local/bin/basex', '/srv/basex/webapp/sync/update_jira.bxs'), (),
map { 'id':'update_jira_job', 'interval':'PT5M', 'base-uri': '/srv/basex/webapp/sync/',
'service': true(), 'log': 'update_jira_job'})
When I run this through the database admin tool query window, it runs right away
14:02:54.494 10.244.144.142:54402 admin 200 296095.32 [POST] /dba/query-update
And then after 5 the minute interval a .05 ms log entry shows up when the service kicked off:
14:57:50.564 JOB:update_jira_job admin OK 0.05 update_jira_job
Please note that BaseX command scripts contain plain database commands, whereas the functions in the Jobs Module were tailored to execute XQuery code. If you want to use jobs:eval, the best solution is to rewrite the contents of your command scripts to XQuery.
If you want to stick with the command scripts, you could indeed try to invoke BaseX via proc:execute, but you should be aware that the two BaseX instance will run independently of each other and could lead to corrupt databases (see https://docs.basex.org/wiki/Startup#Concurrent_Operations).
If the invocation fails…
Cannot run program "basex": CreateProcess error=2, ...
…you may need to address BaseX with the full path:
(: Windows installation :)
proc:execute('c:\Program Files (x86)\BaseX\bin\basex.bat', 'commands.bxs')
(: Linux :)
proc:execute('/path/to/basex', 'commands.bxs')

Exec.Command is executed, but has no effect on Windows 7

I'm trying to print an local image from my Go program using the Exec Package on Windows 7.
The following command line works fine when ran manually:
rundll32.exe shimgvw.dll ImageView_PrintTo /pt C:\Users\XXXXX\IMAGE.jpg "PRINTERNAME"
I tried:
res, err := exec.Command(
"cmd",
"/c",
"rundll32.exe",
"shimgvw.dll",
"ImageView_PrintTo",
"/pt",
"C:\\Users\\XXXXX\\IMAGE.jpg",
"\"PRINTERNAME\"",
).Output();
or
res, err := exec.Command(
"cmd",
"/c",
"rundll32.exe shimgvw.dll ImageView_PrintTo /pt C:\\Users\\XXXXX\\IMAGE.jpg \"PRINTERNAME\"",
).Output();
But in both cases, it just sends back an empty string as a result and no error.
And no effect on the printer tasks list.
I'm sure I'm missing something obvious (something to do with the system environnement when executing the script?). Ideas are welcome!
Thanks.

CoffeeScript --compile order in sub-directories

Is there any way to define CoffeeScript compilation order in sub-directories?
Please consider the following example:
Files:
src/App.coffee
src/view/B.coffee
src/view/a/A.coffee
Where class A extends B.
coffee --join js/app.js --compile src/view/ src/App.coffee
This throws an error in the browser:
Uncaught TypeError: Cannot read property 'prototype' of undefined
If I rename folder a to z, the error is gone and everything works fine.
src/view/z/A.coffee
I would expect the compiler to read all .coffee files from src/view/ before it goes into src/view/ sub-directories. Again, is there any way to do that?
Edit:
PC Windows 7,
CoffeeScript version 1.3.3
The only solution I think is to create the compile order manually within a build script.
You would create an ordered collection with filenames, where as the loop iterates and concatenates a new big string, which can be compiled as one file.
Create a Cakefile with following content, check Syntax first. And run with cake build. That should work, cake comes with CoffeeScript.
fs = require 'fs'
{exec} = require 'child_process'
viewsDir = "src/view"
coffeeFiles = [
'B'
'A'
]
task 'build'
# loops through coffeeFiles.
for file, index in coffeeFiles then do (file, index) ->
fs.readFile "#{viewsDir}/#{file}", 'utf8', (err, content) ->
appCoffee[index] = content
compile() if --remaining is 0
compile = ->
fs.writeFile 'js/app.coffee', appCoffee.join('\n\n'), 'utf8', (err) ->
throw err if err
exec 'coffee --compile js/app.coffee', (err, stdout, stderr) ->
throw err if err
console.log stdout + stderr
# you can skip deleting the app.coffee file
fs.unlink 'js/app.coffee', (err) ->
throw err if err
console.log 'Created app.coffe, compiled to app.js and removes app.coffee'
# maybe additional taks
# invoke 'test'
Documented also in Wiki of Coffeescript https://github.com/jashkenas/coffee-script/wiki/[HowTo]-Compiling-and-Setting-Up-Build-Tools
Before first loop you could also make it loop through different directories. And just list filenames in coffeeFiles to be processed before the others not in listed and the rest could be added to list with fs.readDir().
We created a simple module to solve a similar problem:
https://github.com/Vizir/rehab
Just put #_require [filename].coffee on your file and you're done.
We are using it in productions with complex dependency graphs.