I'm attempting to use a MongoDB Cursor in Haskell. I use a pipe (connection to my MongoDB database) to obtain the value of this cursor, then close the pipe and give the value of the cursor. After opening another pipe, I have errors when accessing the cursor, although the Haskell MongoDB docs state that:
a cursor is not closed when the pipe is closed, so you can open another pipe to the same server and continue using the cursor.
at http://hackage.haskell.org/package/mongoDB-2.5.0.0/docs/Database-MongoDB-Query.html#t:Cursor
I have tried using cursors when the pipe does not close between the initialisation and usage of them: this does work, however this is not the solution I want to integrate into my web-app (I will want to use pooling in the future.) I am also left wondering why closing the pipe causes the cursor to no longer work.
I have looked through the MongoDB source code, and have only found one area where closeCursor is used (https://github.com/mongodb-haskell/mongodb/blob/33f2aca7b736c34d915916bc978bc5435baae533/Database/MongoDB/Query.hs#L1214). I am not sure if the error I'm having is a problem with a mismatch between the documentation of the client and my actual MongoDB Community Server (v4.0.10).
I have created a reproducible example of an IO Action causing this error.
firstFiveOver20 :: IO ()
firstFiveOver20 = (DB.withDB . find $ (select [] "test"))
>>= (() <$) . DB.withDB . Database.MongoDB.nextN 5
find, select, and nextN are from the MongoDB package.
The function withDB is defined as:
withDB :: Action IO a -> IO a
withDB action = (connect $ host "127.0.0.1") >>= (\pipe -> access pipe master databaseName action <* close pipe)
The expected result is for nothing to be logged (as I don't expect any errors). However, the error ConnectionFailure Handle has been closed: does not exist is given. From my perception, this seems to mean that the MongoDB Database is reporting the cursor as not existing. This either means that the Haskell client has closed it or it was closed by the MongoDB Database when the connection was dropped. These both contradict the statement in the docs (http://hackage.haskell.org/package/mongoDB-2.5.0.0/docs/Database-MongoDB-Query.html#t:Cursor).
Related
I'm working on a web app in Rust. I'm using Tokio Postgres, Rocket and Tera (this may be relevant).
I'm using the following to connect to my DB which doesn't fail in either case.
(sql_cli, connection) = match tokio_postgres::connect("postgresql://postgres:*my_password*#localhost:8127/*AppName*", NoTls).await{
Ok((sql_cli, connection)) => (sql_cli, connection),
Err(e) => return Err(Redirect::to(uri!(error_display(MyError::new("Failed to make SQLClient").details)))),
};
My query is as follows. I keep my queries in a separate file (I'm self taught and find that easier).
let query= sql_cli.query(mycharactersquery::get_characters(user_id).as_str(), &[]).await.unwrap();
The get characters is as follows. It takes a user ID and should return the characters that they have made in the past.
pub fn get_characters(user_id: i16) -> String {
format!("SELECT * FROM player_characters WHERE user_id = {} ORDER BY char_id ASC;", user_id)
}
In my main file, I have one GET which is /mycharacters/<user_id> which works. This GET returns an HTML file. I have another GET which is /<user_id> which returns a Tera template. The first works fine and loads the characters, the second doesn't: it just loads indefinitely. I initially thought this was to do my lack of familiarity with Tera.
After some troubleshooting, I put some printouts in my code, the one before and after the SQL call work in /mycharacters/<user_id>, but only the one before writes to the terminal in /<user_id>. This makes me think that Tera isn't the issue as it isn't making it past the SQL call.
I've found exactly where it is going wrong, but I don't know why as it isn't giving an error.
Could someone please let me know if there is something obvious that I am missing or provide some assistance?
P.S. The database only has 3 columns, so an actual timeout isn't the cause.
I expected both of these SQL calls to function as I am connected to my database properly and the call is copied from the working call.
I have written an SNMP trap receiver but currently I have to hardcode all the SNMPv2 community strings to be able to receive the traps.
How do I emulate the 'disableAuthorization' functionality from snmptrapd in pysnmp?
I have tried to not set the community string: config.addV1System(snmpEngine, 'my-area') but this errors about a missing param. I have also tried an empty string: config.addV1System(snmpEngine, 'my-area', '') but this stops all traps being processed.
What is the best way to allow receiving all traps through pysnmp regardless of the community string they were sent with? I haven't found anything in the pysnmp docs that could help me
I had made progress on setting up an observer for V1/2 (V3 to be added later) that picked up on notifications with an unknown community string and then called addV1System on the fly to dynamically add it in, like so:
When setting up the transportDispatcher:
snmpEngine.observer.registerObserver(_handle_unauthenticated_snmptrap,
"rfc2576.prepareDataElements:sm-failure", "rfc3412.prepareDataElements:sm-failure")
And then:
def _handle_unauthenticated_snmptrap(snmpEngine, execpoint, variables, cbCtx):
if variables["securityLevel"] in [ 1, 2 ] and variables["statusInformation"]["errorIndication"] == errind.unknownCommunityName:
new_comm_string = "%s" % variables["statusInformation"].get("communityName", "")
config.addV1System(my_snmpEngine, 'my-area', new_comm_string)
return
else:
msg = "%s" % variables["statusInformation"]
print(f"Trap: { msg }")
However, this will always throw away the first trap received while adding any new community string (and then there is the problem whereby when the daemon is restarted the updated list of community strings is lost).
In looking to improve this I then found hidden away in the docs this little gem:
https://pysnmp.readthedocs.io/en/latest/examples/v3arch/asyncore/manager/ntfrcv/advanced-topics.html#serve-snmp-community-names-defined-by-regexp
This example receives a notification and rewrites the community string into 'public' so all traps will be correctly received.
In essence, when setting up the transportDispatcher:
my_snmpEngine.observer.registerObserver(_trap_observer,
'rfc2576.processIncomingMsg:writable', cbCtx='public')
And then:
def _trap_observer(snmpEngine, execpoint, variables, community_string):
variables['communityName'] = variables['communityName'].clone(community_string)
I am trying to build a subscriber function that goes like this:
Every user register his machine name to a list using
hostname:enlist .z.h
The function loops through the hostname list, creates connection and do some function {u:hopen(`:x:200;5000);u"somefunction[]"} each hostname
The only issue is .z.h is of a symbol where x should have no type in order to have this: u:hopen(`:HURNMW052:200;5000) instead of this u:hopen(`:`HURNMW052:200;5000)
The same thing happens using IPs ”.” sv string”h”$0x0 vs .z.a = "161.16.16.23" not 161.16.16.23
Any idea how I could cast those or other solutions to create a loop of handles?
You can use a string to open a connection. See below.
q)":",string[.z.h],":8009"
":homer:8009"
q)h:hopen(":",string[.z.h],":8009";5000)
q)h
3i
This reference on the kx wiki is useful for opening connections in kdb.
In a parameterized query issued from c# code to PostgreSQL 10.14 via dotConnect 7.7.832 .NET connector, I select either a parameter value or the local timestamp, if the parameter is NULL:
using (var cmd = new PgSqlCommand("select COALESCE(#eventTime, LOCALTIMESTAMP)", connection)
When executed, this statement throws the error in subject. If I comment out the corresponding parameter
cmd.Parameters.Add("#eventTime", PgSqlType.TimeStamp).Value = DateTime.Now;
and hardcode
using (var cmd = new PgSqlCommand("select COALESCE('11/6/2020 2:36:58 PM', LOCALTIMESTAMP)", connection)
or if I cast the parameter
using (var cmd = new PgSqlCommand("select COALESCE(cast(#eventTime as timestamp without time zone), LOCALTIMESTAMP)", connection)
then it works. Can anyone explain what # operator in the error is referring to and why the error?
In the case that doesn't work, your .Net connection library seems to be passing an SQL command containing a literal # to the database, rather than substituting it. The database assumes you are trying to use # as a user defined operator, as it doesn't know what else it could possibly be. But no such operator has been defined.
Why is it doing that? I have no idea. That is a question about your .Net connection library, not about PostgreSQL itself, so you might want to add tag.
The error message you get from the database should include the text of the query it received (as opposed to the text you think it was sent) and it is often useful to see that in situations like this. If that text is not present in the client's error message (some connection libraries do not faithfully pass this info along) you should be able to pull it directly from the PostgreSQL server's log file.
I am trying to copy a remote mongodb atlas server to a local one. I do this by a python script which also checks if the record is already there. I see that eventhough the local database is empty my script find duplicates, which are not in the remote mongodb atlas (at least i cannot find them). I am not so experienced with mongodb and pymongo but I connot see what I am doing wrong. Sometimes Find_one() finds exactly the same record as before (all the fields are the same even the _id) ?
I removed the collection completely from my local server and tried again, but still the same result.
UserscollectionRemote = dbRemote['users']
UserscollectionNew = dbNew['users']
LogcollectionRemote = dbRemote['events']
LogcollectionNew = dbNew['events']
UsersOrg = UserscollectionRemote.find()
for document in UsersOrg: # loop over all users
print(document)
if UserscollectionNew.find_one({'owner_id': document["owner_id"]}) is None: # check if already there
UserscollectionNew.insert_one(document)
UserlogsOrg = LogcollectionRemote.find({'owner_id': document["owner_id"]}) # get all logs from this user
for doc in UserlogsOrg:
try:
if LogcollectionNew.find_one({'date': doc["date"]}) is None: # there was no entry yet with this date
LogcollectionNew.insert_one(doc)
else:
print("duplicate");
print (doc);
except:
print("an error occured finding the document");
print(doc);
You have the second for loop inside the first; that could be trouble.
On a separate note, you should investigate mongodump and mongorestore for copying collections; unless you need to be doing it in code, these tools are better suited for your use case.