How to get all collection names in MongoDb using C++ - c++

There is a great MongoDb C++ Driver. The only thing that makes it hard for newbies like me to use it - is the lack of teeny-weeny examples. For instance, I know there is a method called getCollectionNames, but I'm not sure how to use it. In Python I would do it like this:
db = MongoClient(host, port)[db_name]
colls = db.collection_names()
and I'm done. But I don't feel so comfortable with C++ and can not figure out myself how to convert raw function declarations in documentation to some working code.
So, this is what I've done by now and see that it works:
ConnectionString cs = ConnectionString::parse(uri, errmsg);
DBClientBase * conn(cs.connect(errmsg));
Now I want to make one step further and get all collection names. Please, give some advice.
EDIT
Well, I found a method somewhere in dbclientinterface.h called getCollectionNames. It is defined like so:
std::list<std::string> getCollectionNames( const std::string& db,
const BSON& filter = BSONObj())
But I find this sole declaration without any informative hints completely useless. It is just a sum of letters and no more.
EDIT
I found a solution and I will post it below.

This is the solution:
std::string uri = "mongodb://127.0.0.1:27017/mydb";
std::string errmsg;
ConnectionString cs = ConnectionString::parse(uri, errmsg);
DBClientBase * conn(cs.connect(errmsg));
std::list<std::string> colls = conn->getCollectionNames("mydb");
for(std::list<std::string>::iterator it = colls.begin();it != colls.end();++it){
do_something(*it);
}

Related

Setting a WinRt AdvertisementFilter() to a substring of LocalName

C++, WinRT, VS2017, Win10
I create a watcher to look for my Bluetooth LE device with
BluetoothLEAdvertisementWatcher watcher;
Now I want to set a filter for for the device that I am specifically looking for. Let's say that the LocalName for the device is "MyDevice_ABC1234". I can do this with
watcher.AdvertisementFilter().Advertisement().LocalName().c_str() == L"MyDevice_ABC1234";
But what I really want to do is set the filter to the manufacture's name and not the specific model number. I want to filter for "MyDevice" being in the LocalName. This would be easy enough given the luxury of a few lines of code but how would it be done in the context of
watcher.AdvertisementFilter().Advertisement().LocalName()
LocalName() has an operator for basic_string_view which has a find() method but for the life of me I can't get that to work properly. The find() is supposed to return the npos so I tried:
watcher.AdvertisementFilter().Advertisement().LocalName().operator std::basic_string_view<wchar_t, std::char_traits<wchar_t>>.find("MyDevice") == 8;
I actually tried this as simple code so I could debug the results with
hstring hstrLocalName = L"MyDevice_aBC1234";
bool bFind = hstrLocalName.operator std::basic_string_view<wchar_t, std::char_traits<wchar_t>>.find("MyDevice", 0) == 8;
and also
int iFind = hstrLocalName.operator std::basic_string_view<wchar_t, std::char_traits<wchar_t>>.find("MyDevice", 0);
But neither of these worked. They compiled but just never executed. Is there a way to get the basic_string_view.find() to work or would there be a better way to do this?
I see now, that when I do use the method mentioned above from StackOverflow here, it does filter for the LocalName that I set. However, and I remember this warning from the docs somewhere, that some advertisement packets come with the local name but not Uuids and visa versa. As it happenes, that is why I thought the filter was catching nothing. I was ignoring any packets that did not have services and these were the ones with the LocalName. Catch22.
For what it is worth, here is the method for setting a filter mentioned in the link above that also worked for me (with caveats)
auto filter = BluetoothLEAdvertisementFilter();
auto advert = BluetoothLEAdvertisement();
advert.LocalName(L"MyDevice_ABC1234");
filter.Advertisement(advert);
watcher.AdvertisementFilter(filter);

VSIX how to get current snapshot document name?

I have been trying to to create an extension that highlights specific line numbers for me in Visual Studio in the margins.
I manged to get my marking in the margins using predefined line number but for it to work properly I need to know what the current document FullName is (Path and filename)
After much googling I figured out how to do it with the sample code (which is not ideal)
DTE2 dte = (DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.15.0");
var activeDocument = dte.ActiveDocument;
var docName = activeDocument.Name;
var docFullName = activeDocument.FullName;
Now I know the problems here
is that is for specific version bases on the text
there is no way to select which instance (when running more than one VS)
It seems to be very slow
I have a feeling I should be doing this with MEF Attributes but the MS docs examples are so simple that they do not work for me. I scanned a few SO questions too and I just cannot get them to work. They mostly talk about Services.. which I do not have and have no idea how to get.
The rest of my code uses SnapshotSpans as in the example Extension of Todo_Classification examples which is great if you do NOT need to know the file name.
I have never done any extensions development. Please can somebody help me do this correctly.
You can use following code to get a file from a snapshot without any dependencies.
public string GetDocumentPath(Microsoft.VisualStudio.Text.ITextSnapshot ts)
{
Microsoft.VisualStudio.Text.ITextDocument textDoc;
bool rc = ts.TextBuffer.Properties.TryGetProperty(
typeof(Microsoft.VisualStudio.Text.ITextDocument), out textDoc);
if (rc && textDoc != null)
return textDoc.FilePath;
return null;
}
If you don't mind adding Microsoft.CodeAnalysis.EditorFeatures.Text to your project it will provide you with an extension method Document GetOpenDocumentInCurrentContextWithChanges() on the Microsoft.VisualStudio.Text.Snapshot class. (Plus many other Rosyln based helpers)
using Microsoft.CodeAnalysis.Text;
Document doc = span.Snapshot.GetOpenDocumentInCurrentContextWithChanges();

Get query from sqlite3_stmt of SQLite in c/cpp [duplicate]

I'm using SQLite (3.6.4) from a C++ application (using the standard C api). My question is: once a query has been prepared, using sqlite3_prepare_v2(), and bound with parameters using sqlite3_bind_xyz() - is there any way to get a string containing the original SQL query?
The reason is when something goes wrong, I'd like to print the query (for debugging - this is an in-house developer only test app).
Example:
sqlite3_prepare_v2(db, "SELECT * FROM xyz WHERE something = ? AND somethingelse = ?", -1, &myQuery, NULL);
sqlite3_bind_text(myQuery, 1, mySomething);
sqlite3_bind_text(myQuery, 2, mySomethingElse);
// ....
// somewhere else, in another function perhaps
if (sqlite3_step(myQuery) != SQLITE_OK)
{
// Here i'd like to print the actual query that failed - but I
// only have the myQuery variable
exit(-1);
}
Bonus points if it could also print out the actual parameters that was bound. :)
You probably want to use sqlite3_trace
This will call a callback function (that you define) and on of the parameters is a char * of the SQL of the prepared statements (including bound parameters).
As per the comments in sqlite3.c (amalgamation), sqlite3_sql(myQuery) will return the original SQL text.
I don't see any function for finding the value bound at a particular index, but we can easily add one to the standard set of SQLite functions. It may look something like this:
const char* sqlite3_bound_value(sqlite3_stmt* pStmt, int index)
{
Vdbe *p = (Vdbe *)pStmt;
// check if &p->aVar[index - 1] points to a valid location.
return (char*)sqlite3ValueText(&p->aVar[index - 1], SQLITE_UTF8);
}
Well, the above code shows only a possible way sqlite3_bound_value() could be implemented. I haven't tested it, it might be wrong, but it gives certain hints on how/where to start.
Quoting the documentation:
In the "v2" interfaces, the prepared statement that is returned (the sqlite_stmt object) contains a copy of the original SQL text.
http://www.sqlite.org/c3ref/prepare.html

Compiling old C++ classes under Borland C++Builder XE

Currently, I'm working on compiling old .cpp classes under C++ Builder XE. Apart from many troubles, there is one which I have completely no idea how to solve.
My code:
String txt = "<Not so long sql query>";
int licz = some_function(txt, dzeFDS); //1
//assigning licz to somewhere
txt = "<much longer query>";
licz = some_function(txt, budFDS); //2
Problem is that during second call of some_function program is stopped and i have this alert:
First chance exception at $75A1C42D. Exception class EDatabaseError with message 'budFDS: Type mismatch for field 'Function', expecting: String actual: WideString'. Process Call.exe (1896)
It's strange form be, bacause first call of some_function works fine, but this second one (with arguments with the same type) doesn't.
some_function code:
int __fastcall some_function(String txt, TIBDataSet *firDS)
{
firDS->Close();
firDS->SelectSQL->Text = txt;
firDS->Open(); //during debugging, exception occurs in this line
int count = 0;
while(!firDS->Eof)
{ count++;
firDS->Next();
}
return count;
}
Any ideas what why it happens?
Thanks in advance
There is much pain in your future.
Anyway, the problem you're having is with the database connection. There's a field in your database called "Function" that holds a string. This field came across as a String with the ancient database driver that this program originally used. Your shiny, new database driver is telling VCL to expect such things as Unicode, and VCL doesn't like to shove such things into plain Strings, so it expects you to have a WideString ready in which to shove it.
Fortunately, there are ways of beating VCL into submission. What you want to do, since you surely don't want to rewrite half the application by changing TIBDataSet, is to tell the connection not to bother with Unicode. In order to do this, you have to set up the TSQLConnection object with UseUnicode=false, which I hope (I have no way of testing VCL code anymore) should look something like this:
connection->Params->Add("UseUnicode=false");
Where connection is the TSQLConnection object. I think you have to do this before connecting to the database.
If that doesn't work, see if you can configure the database driver to not use Unicode.
Problem solved - this one field Function has other type in C++ Builder design view - it was TStringField, and rest fields has TIBStringField...

C# Equivalent to ifstream/ofstream in C++

I know this has probably been asked before, but I can't find it here on SO anywhere, and I can't get a clear answer on anything I look up on Google either.
I need to know the C# equivalent to C++'s ifstream/ofstream.
For instance, if I had the following C++ code:
ifstream input("myFile.txt");
ofstream output;
output.open("out.txt");
What would be the C# equivalent?
I found a site that said (for the in file portion, anyway) that the equivalent was this:
using System.IO;
FileStream fs = new FileStream("data.txt", FileMode.Open, FileAccess.Read);
I tried putting this in:
FileStream fs = new FileStream(input, FileAccess.Read);
I don't have the "FileMode" in mine because VS didn't recognize it. And "input" is a string in the parameters that holds the string value of the input file name (for example - "myFile.txt").
I know I've got to be missing something silly and minor, but I can't figure out what that is. Any help on this would be much appreciated!
I'm developing in VS2010, C#-4.0, WPF API.
FileStream is what you want. Take a look at the MSDN example on stream composition here.
I feel that StreamReader/StreamWriter offer similar functionality to c++'s ifstream/ofstream. FileStream is for dealing with byte[] data, whereas StreamReader/StreamWriter deal with text.
var writer = new StreamWriter(File.OpenWrite("myFile.txt");
writer.WriteLine("testing");
writer.Close();
var reader = new StreamReader(File.OpenRead("myFile.txt");
while ( !reader.EndOfStream )
{
var line = reader.ReadLine();
}