Let's say I have a string. " db.getCollection("somecollection").find({})". Can I execute this string as a query in C#? i.e. I get a string. And I just execute it as a query but in c#
I just want like this
string query = "db.getCollection("somename")";
Mongo.execute(query);
no, the best you can do in this context is to use db.RunCommand<BsonDocument>("{ ping : 1 }") (c#) which is close to the shell db.runCommand({ ping : 1 })
UPDATE:
you may look at this as well How to execute mongo commands through shell scripts?, I'm not familiar with this and it doesn't work for me on windows and 5.0 server in most of the cases mentioned there other than simple one: mongo --eval "printjson(db.serverStatus())", but if you will be able to make this suggested script mongo < script.js (or similar) work in, for example, the shell, you will be able to put your random query in this file(script.js) and then, add this file as argument into Process creating similar to:
using (var process = new Process())
{
// arguments below may require the whole path to the files
process.StartInfo.Arguments = "script.js";
process.StartInfo.FileName = "mongo";
process.Start();
}
to read results, you will need analyzing process.StandardOutput/process.StandardError stream.
Related
I am trying to use DB2's Command Line processor. When using it on the command line, I enter: db2cmd then a 2nd window opens where I can connect to the database and submit queries. I am attempting to write a wrapper for the CLP and when I access the command line, it opens the DB2 CLP in a 2nd window and I can't figure out how to send arguements to the new window. Here is what I have:
static void Main(string[] args)
{
var p = new Process();
var info = new ProcessStartInfo();
info.FileName = "db2cmd";
info.RedirectStandardInput = true;
info.UseShellExecute = false;
info.CreateNoWindow = true;
p.StartInfo = info;
p.Start();
using (var sw = p.StandardInput)
{
sw.WriteLine("DB2 CONNECT TO dbname USER \"username\" USING \"password\"");
sw.WriteLine("DB2 SELECT * FROM SPYPRD.CLMDTL FETCH FIRST 10 ROWS ONLY");
}
}
Maybe better to use an alternative interface (e.g. the ADO .net interface) from C# instead of using the CLP.
To use commands like LOAD and EXPORT etc, from ADO (or jdbc/odbc etc) you invoke them via stored procedure SYSPROC.ADMIN_CMD() if the Db2-server runs on Linux/Unix/Windows. Pay attention to the details in the documentation for that stored procedure because all file names are relative to the Db2-server (not the workstation).
Not sure if CLP accepts stdin redirection for passwords - you would also need to parse the stdout, maybe messy.
If the database is local then you can use the CLP without needing a userid/password on the CONNECT statement. If you wish to connect with different credentials use runAs to specify the credentials independently of the CLP, to avoid needing to send arguments to the CLP.
If the database is remote and is on Linux/Unix/Windows, best to use an alternative interface than CLP (e.g. ADO etc), or consider shipping the script to the remote-server to run locally on the Db2-LUW server as the required-user again avoiding passwords(e.g. if the Db2-server runs on Linux/Unix/Windows, use tools equivalent to psexec or ssh etc).
I want to be able to run any MongoDB command from C#. I know that this can be done. I start with a simple example, instead of using the dropDatabase method from the C# driver I am trying to drop a database using the db.runCommand method as follows.
I have tried in two ways, passing the command as a string and also passing the command as a BsonDocument but nothing is working and I don't have any clues where I'm wrong even after researching on the internet I cannot find a suitable example.
I'm having a really hard time to identify why this piece of code is not working.
Command passed as a string:
database.RunCommand<string>("{dropdatabase : 1}");
Command passed as a BSON document:
var command = new BsonDocument { {"dropdatabase", "1" } };
var execute = database.RunCommand<BsonDocument>(command);
You can use a JsonCommand like this:
var command = new JsonCommand<BsonDocument>("{ dropDatabase: 1 }");
db.RunCommand(command);
or use a CommandDocument like this:
var command = new CommandDocument("dropDatabase", 1);
db.RunCommand<BsonDocument>(command);
I'm currently trying to pipe multiple parameters to the adb.exe file in the google sdk. an example of my inputs are:
adb shell getprop ro.build.version.release
adb shell getprop ro.product.brand
which are outputting correct from my application. Though, the problem is I want to populate a list view of information, the problem that i'm currently encountering though, is the method to pipe commands to get desired output. I've currently got:
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "Resources/adb.exe",
Arguments = "devices",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
string Output = proc.StandardOutput.ReadToEnd().ToString();
This currently returns as expected, but i'm wishing to get multiple results from piping something like:
Arguments = "devices ro.build.version.release ro.product.brand"
This provides no avail, even when piping directly into command prompt.
adb shell getprop devices ro.build.version.release ro.product.brand
empty, I have come around with a (assumingly) load heavy solution, which is to move the initialization of the executional into it's own function to be called multiple times. See code below:
public string GetInfo(string CommandArg)
{
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "Resources/adb.exe",
Arguments = CommandArg,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
return proc.StandardOutput.ReadToEnd().ToString();
}
public void SetDefineInformation()
{
AndroidVersion = decimal.Parse(GetInfo("ro.build.version.release"));
DeviceModel = GetInfo("ro.product.device");
...
}
To me, this seems like a load heavy task with constantly opening a single executable for it to close then re-open until the task is complete. Is there an overall work around, which might allow one to pipe multiple parameters to an executional and get the desired results?
adb can start a shell so you could create the shell with adb shell then redirect stdin and stdout to write to it directly
No measurable performance gain would come from the "optimization" you are proposing. The adb code is pretty efficient. The overhead it introduces is very minimal. Specially in the client part. Most of the delay comes from waiting for the device's response anyway.
So stop overcomplicating things and just run multiple adb shell sessions. If loading the adb binary bothers you so much - just use sockets to talk to the adb server directly. Take a look at the Mad Bee library code to see how to do it in c#. Or just use the library.
As for optimizing querying multiple system properties - just use adb shell getprop command to pull all properties at once.
I don't agree that this question was answered effectively: decode mysqlbinlog in C#.
I have, what I think is the same question: I want to read the MySql binlogs from within a c# application, but do not know the format of the file. How can I properly parse these files' data?
First, what I learned:
Most of the source code files for MySql are installed along with the assemblies and generally located in [basedir]\include. For example, a typical install would place the files in Program Files\MySql\MySql 5.6\include.
mysqlbin.cc was NOT in that folder. However, I was easily able to get the file by doing a quick Google search. The file can be found here: https://code.google.com/p/mg-common-utils/source/browse/trunk/myreplicator/src/mysqlbinlog.cc?r=4 . It is well documented and easy to read.
Second, my solution:
As akuzminsky pointed out, the format of MySql's binlog is subject to change. However, the format returned from the mysqlbinlog.exe utility is consistent. This application is typically included in a MySql install and should be located in [basedir]\bin. I now run this application from within a c# Console Application and parse the results. I used the following steps to accomplish this:
Enabled binlogging on the MySql server from within the options file. In MySql Workbench, check 'log-bin' under the logging tab. Or, type 'log-bin=' in the settings file (often located in [basedir]. Might be called 'my.ini' or 'my.cnf' or something else. Generally, with .cnf or .ini extension). A filename is not required. When one is not specified, MySql will automatically create filenames for the logs. However, review MySql documentation on possible issues with this.
From within my client application, I query the server to get the path of each binary log (there could be many). To do this:
query show global variables like 'datadir' //returns the data directory.
query show binary logs //returns the filename of each binary log, along with its file size (helpful for reading).
Parsing these together gets the path for each binary log.
Since mysqlbinlog.exe is located in [basedir]\bin, I query the server to get the path of the base directory:
query show global variables like 'basedir'
Then, I parse the result with '\bin\mysqlbinlog.exe'
I use the Process class to create a new process, execute each binary log using mysqlbinlog.exe, and read each files results into a string variable:
private static string GetLogTexts(Liststring> logfilenames)
{
List<string> _logtexts = new List<string>();
string _basedir = GetBaseDir();
foreach(string logfilename in logfilenames)
{
Process proc = new Process();
proc.StartInfo.FileName = _basedir + "\\bin\\mysqlbinlog";
proc.StartInfo.Arguments = string.Format("\"{0}\"", logfile);
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardInput = proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
_logtexts.Add(proc.StandardOutput.ReadToEnd());
}
return _logtexts;
}
private static string GetBaseDir()
{
string path = "";
using (MySqlConnection conn = new MySqlConnection(RemoteServerConnectionString))
{
conn.Open();
using (MySqlCommand cmd1 = new MySqlCommand("show global variables like 'basedir'", conn))
{
using (MySqlDataReader reader = cmd1.ExecuteReader())
{
while (reader.Read())
{
path = reader.GetString(1);
}
}
}
}
return path;
}
Finally, I parse the results using my own logic (specific for what I am looking for). The results are very easy to read: mysqlbinlog uses regular line breaks and statements are terminated by a delimiter, which is defined prior to the statement (as usual, there can be multiple delimiters).
I hope this helps someone!
I was following one of the thread to run perl scripts from my c# program.
My c# code is like this:
private void RunScript(ArrayList selectedScriptFileList)
{
foreach (var curScriptFileName in selectedScriptFileList)
{
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo("perl.exe");
myProcessStartInfo.Arguments = (string)(curScriptFileName);
myProcessStartInfo.UseShellExecute = false;
myProcessStartInfo.RedirectStandardOutput = true;
myProcessStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
myProcessStartInfo.CreateNoWindow = true;
myProcess.StartInfo = myProcessStartInfo;
myProcess.Start();
myProcess.WaitForExit();
string output = myProcess.StandardOutput.ReadToEnd();
this.ScriptTestResultTextBox.AppendText(output);
}
}
And my perl script requires XML parsing. I can read the print statement before the XML parsing, but not after the parsing starts. The script runs find on DoS shell.
Here is part of my script:
print("\n");
print("****************** test1.pl ***********************\n");
print("\n");
print("1");
print("2");
my $scriptName = 'test1.pl';
my $file = '../../ScriptParamLib.xml';
my $parser = XML::LibXML->new();
my $tree = $parser->parse_file($file);
my $root = $tree->getDocumentElement;
my #species = $root->getElementsByTagName('test_node');
print("Accessing XML Data Base...\n");
The c# testbox only shows the first three print statement but not the last one.
Does anybody knows why?
Thanks
You could add more debugging print statements (e.g. one between every other line of your code) to see how far the execution gets. However, I'm going to go on a hunch and suggest that adding these three lines to your script will either solve the problem outright or lead you closer to a solution:
use strict;
use warnings;
use XML::LibXML;
Please update your question indicating how far execution gets and what errors you see!
I figured I should roll my comments into an answer since they proved to be helpful:
Since using an absolute path for $file in the Perl script works, the issue most likely has something to do with the working directory of the process that gets spawned from the C# program. You can use the Cwd module in the Perl script to see what the working directory actually is. If it's not what you expect, try setting it via the WorkingDirectory property of ProcessStartInfo in your C# program. Relative paths should work just fine after that.