Adding Helper Methods to Mongo Shell - bash

Is there any way of adding "helper" methods to the mongo shell that loads each time you use it?
Basically whenever you want to query by _id, you have to do something like this.
db.collectionName.findOne({_id: ObjectId('THIS-IS-AN-OBJECTID')})
Whenever I'm going to be doing a lot of command line commands, I alias the ObjectId function to make it easier to type.
var ob = ObjectId;
db.collectionName.findOne({_id: ob('AN-OBJECTID')})
db.collectionName.findOne({_id: ob('ANOTHER-ONE')})
db.collectionName.findOne({_id: ob('ANOTHER')})
It would be pretty chill if there was a way of either running a specified piece of JS / add a chunk of code that runs each time mongo is pulled up from the shell. I checked out MongoDB's CLI documentation, but didn't see anything like that available, so I figured I would ask here.
I know there is a possibility of using this nefariously, so this might be a situation where it might be unsupported by the mongo shell by default. This might be a situation where we can create a helper bash script of some sort to launch the shell, then inject keyboard input to create the helper ob function? Not sure how this could be tackled personally, but would love some insight on how to do something like this, either natively or through a helper script of some sort.

If you want code to execute every time you launch the shell, then whatever you place in .mongorc.js will be run on launch:
.mongorc.js File
When starting, mongo checks the user’s HOME directory for a JavaScript file named .mongorc.js. If found, mongo interprets the content of .mongorc.js before displaying the prompt for the first time. If you use the shell to evaluate a JavaScript file or expression, either by using the --eval option on the command line or by specifying a .js file to mongo, mongo will read the .mongorc.js file after the JavaScript has finished processing. You can prevent .mongorc.js from being loaded by using the --norc option.
So simply define your variable association there.
You could also supply a file of your choice along with the --shell option to let the command know you want the shell opened on completion of any instructions contained:
mongo --shell file_with_javascript.js
But as mentioned, the .mongorc.js file would still be called (if present) unless the --norc option was also specified.

Related

How to determine database relations from PASE/Qshell?

I'm just stepping into the world of PASE and Qshell on the IBM i, and am still learning the "shell way" of solving problems.
I'm trying to write a shell script that will delete all logical files in a given library that are associated with a given physical file. The OS is IBM i 7.2. In QSYS-land, I'd probably DSPDBR on the physical file to an outfile, then read through the outfile and delete each dependent file. How would you do this in PASE or Qshell? I had a couple ideas, but they all seem overly-complicated, and the more I learn about shell scripting, the more shortcuts I'm finding.
My first idea was to basically replicate the above process, doing something like this and then somehow using the output of the SELECT:
system "DSPDBR FILE(MYLIB/MYFILE) OUTPUT(*OUTFILE) OUTFILE(QTEMP/DSPDBR)"
db2 "select WHREFI from QTEMP/DSPDBR where WHRELI = 'MYLIB'"
(I see now that QTEMP doesn't really work as a temporary library, but maybe there's a way around this.)
My second idea was to do something like pipe the output of the DSPDBR statement into something like awk to pick out the logical file names, and redirect the output of that to a stream file (or shell variable?). And from there, somehow use this list to delete the logical files.
Is there a more straightforward approach? It seems like whatever the answer is, it will be a pattern that is often repeated when writing shell scripts to interact with QSYS commands and objects.
First, you might review Running SQL queries from PASE instead of QSH. The db2 utility is part of Qshell and not PASE. Unfortunately, the processing behind it is based in ILE, so it's not directly usable within the PASE (AIX run-time) environment. The linked question provides a method of bridging between the two.
However, directly in QShell, you can experiment with something like this:
db2 "SELECT substr(VIEW_NAME,1,18), substr(OBJECT_NAME,1,10),
substr(OBJECT_SCHEMA,1,10), substr(VIEW_SCHEMA,1,10),
substr(TABLE_NAME,1,18)
FROM qsys2.sysviewdep
WHERE OBJECT_SCHEMA = '<yourSchemaName>'"
The SUBSTR() functions might or might not be useful. It depends on your name lengths and whether you want them limited or not. The output can be redirected to an outfile or perhaps piped into sed or another utility for manipulation.
A QTEMP library is specific to [is scoped to] the process that implements the request in the shell. Ensure all of the requests that depend on the same QTEMP library will run in the same process; the system utility runs in a separate process, as does the db2 utility. For example, in the following command-line invocation of the QSHell, all of the requests dependent on QTEMP will run in the same process in which the db2 utility runs; the db2 utility runs a script [or could instead run a dynamic compound statement] that in this scenario was generated by the scripted requests for\within the shell utility:
qsh cmd('
echo "call qsys2.qcmdexc
(''dspdbr mylib/myfile output(*outfile) outfile(qtemp/dspdbr)'')
" >> mydb2.script
; echo "select WHREFI from QTEMP.DSPDBR where WHRELI =''MYLIB''
" >> mydb2.script
; db2 -f mydb2.script
; rm mydb2.script
')
There is an open source equivalent of the QShell db2 command: https://bitbucket.org/litmis/db2util

Setting multiple values for Vim command -complete attribute

I am trying to enable command completion for a custom command that I am setting up for a plugin in the following manner:
command! -complete=shellcmd -nargs=* EScratch call s:ShellScratch(<f-args>)
I would like to enable complete options for shellcmd and file. However it seems that the complete attribute would only take 1 option.
To give a bit more context as to what I am trying to achieve: I am working on a plugin to create a simple scratch buffer. I would like to be able to run a shell command from the command mode and copy the output to the scratch buffer. I have been able to achieve all this but it would be much more productive to have auto completion similar to shell. The complete script can be viewed here https://github.com/ifthikhan/vimscratch/blob/master/plugin/vimscratch.vim. Any pointers will be highly appreciated.
Unfortunately, you can't. If you really need this, you have to either
define two separate commands, e.g. :ScratchShell and :ScratchFile, with the corresponding completions, or
use a -complete=custom[list] and provide your own complete function, where you have to re-implement both sources yourself. Filename completion actually is quite easily done with glob(); I'm not so sure about shell commands.

What exactly is going on in Proc::Background?

I am trying to write a script that automates other perl scripts. Essentially, I have a few scripts that rollup data for me and need to be run weekly. I also have a couple that need to be run on the weekend to check things and email me if there is a problem. I have the email worked out and everything but the automation. Judging by an internet search, it seems as though using Proc::Background is the way to go. I tried writing a very basic script to test it and can't quite figure it out. I am pretty new to Perl and have never automated anything before (other than through windows task scheduler), so I really don't understand what the code is saying.
My code:
use Proc::Background;
$command = "C:/strawberry/runDir/SendMail.pl";
my $proc1 = Proc::Background -> new($command);
I receive an error that says no executable program located at C:... Can someone explain to me what exactly the code (Proc::Background) is doing? I will then at least have a better idea of how to accomplish my task and debug in the future. Thanks.
I did notice on Proc::Background's documentation the following:
The Win32::Process module is always used to spawn background processes
on the Win32 platform. This module always takes a single string
argument containing the executable's name and any option arguments.
In addition, it requires that the absolute path to the executable is
also passed to it. If only a single argument is passed to new, then
it is split on whitespace into an array and the first element of the
split array is used at the executable's name. If multiple arguments
are passed to new, then the first element is used as the executable's
name.
So, it looks like it requires an executable, which a Perl script would not be, but "perl.exe" would be.
I typically specify the "perl.exe" in my Windows tasks as well:
C:\dwimperl\perl\bin\perl.exe "C:\Dropbox\Programming\Perl\mccabe.pl"

Extending tcsh completion

I must work with tcsh.
I am using an internal tool that provides basic completion for some of its commands.
I would like to extend the completion.
I mean that in future releases the default completion may evolve.
I tried something like this:
set def_cmpl = complete tool
complete tool $def_cmpl 'n/-l/(reg short long gui)/'
But I don't understand the result I get.
Indeed, the quotes inside $def_cmpl are doubled:
tcsh> complete tool
''n#-t#$script#'' n/-l/(reg short long gui)/'
I tried some tricks with echo, sed, etc. but I can't avoid those ''.
Could somebody help me?
Please don't say go on bash... The tool doesn't support it...
Finally, I did not find a solution to keep the data inside the script. So, the solution was to redirect the output of the complete command inside a file and then to append new lines to the file.

Shell script to grab selected text and alter it?

How can I make a shell script that will know where the caret is and grab selected text, so I can wrap the text in something? For example, this is a script from a Textmate bundle:
<${1:p}>$TM_SELECTED_TEXT</${1/\s.*//}>
It grabs the text and wraps it in open/close HTML tags. And it is variable so the second tag is mirrored as you type the first.
I want to make a script like this but outside of Textmate so I can use it in TextEXpander.
Does this make sense ? :)
$TM_SELECTED_TEXT is not an environment variable provided to scripts running outside of TextMate -- it is a variable that is set by TextMate and provided to scripts that are run as part of its snippet system. It is not even provided to the Shell bundles "Run Script" command.
What you want to do may be doable through other shell facilities (e.g., sed) so the functionality can be replicated by a shell script -- it depends on your usage scenario.

Resources