No 'changes' key for replacing the same document in RethinkDB - rethinkdb

I am replacing one of my documents with a document that happens to be exactly the same as the one which is already saved in the database. I am doing replace with return_values=True and I expect that the result would contain a changes key. But what I get back after the operation is:
{u'skipped': 0, u'deleted': 0, u'unchanged': 1, u'errors': 0, u'replaced': 0, u'inserted': 0}
I would have expected to get back that key together with the old and new values, which would be the same.
I know my wanted behavior worked at a previous point, but when did it change? And how can I have the old behavior again?

That behaviour was changed in RethinkDB 2.0. There is a proposal for making the old behaviour available:
https://github.com/rethinkdb/rethinkdb/issues/4068

Related

Spring Data JPA fetching list always returns at least a single result

I've noticed a slight problem with how my API is working where I'm using Spring Data JPA.
My query looks something along the lines of:
#Query("SELECT p.id AS id, COUNT(l) AS likes FROM Post p LEFT JOIN Like l ON l.post = p WHERE p.location.id = ?1")
My actual query is bigger, this this contains everything necessary to explain what the issue is. This query will return a list, but assume the location does not exist, it should return null or an empty list, correct? Oh, how wrong you are, my sweet summer child!
This query will instead always return a list of at least one element, regardless of whether or not there are any posts linked to said location.
[{"id": null, "likes": 0}]
That is what the result looks like when serialized to JSON. I am not quite sure what to do about this little predicament, as I obviously don't want to return a list with faulty data, but needing to use processing to filter out duds also seems dumb and unnecessary.
Is there any way to prevent this that I've yet to find? If it is of any relevance, I am using projections currently for my responses.
What I've tried so far:
Adding a not null condition for fields. Does not work, ignored by COUNT.
Adding constraints to all fields #NotNull. Does not work, will still become null.
For what it's worth, I've tried different kinds of joins, though anything but LEFT JOIN doesn't make much sense.
I haven't been able to find any other case which resembles this either, although it most likely exists, but is drowned out by everything else. I'm not quite sure what can be done in this regard, so I'm curious if it's just a quirk with the framework, or if there is an actual solution.
It might be possible to solve through native queries, but I would prefer not to use them.
I'm no SQL expert but I believe that a left join will give you this result if the ID does not exist.
Have you run the query in your DB? Doesn't it give you one row in your result set for IDs that do not exist?
I believe this is intended to say there is a 0 match.
You might want to validate your query before running it. Meaning checking that the location exists first.
As the issue is inherently due to a COUNT and CASE keyword in my real query, resulting in there always being at least one row, and I can't find any method of doing this automatically, the solution I've used is the following:
List<Item> items = repository.customQuery(id);
if (0 < items.size() && null == items.get(0).getId()) {
items.remove(0);
}
The first condition is arbitrary as I know there is always at least one entry, but is done just as a safety measure. A try-catch block would do the trick as well. In the case where you use a primitive int instead of Integer, you'd need to initialize the value in the constructor to something which would normally never be present in the database, such as -1.
If anyone knows of a better method, I'd love to know about it.

Get index of an SKPoint in an SKPath

I'm not seeing an IndexOf or FindIndex method for SKPath.Points. I need to be able to get neighbouring points on both sides of a specified point. Path.Iterator only has .Next, so I am looking for using the index of the SKPoint instead.
With IndexOf or FindIndex seemingly missing, I am thinking of inheriting and maintaining a 2nd dataset in the background for getting the index.
Am I missing something obvious? How are others getting the index, so far?
This post helped. Calling IndexOf directly on Array works. Just need to make sure your SKPoint X and Y are unique from other SKPoints stored in the SKPath.Points. It is doing the check based on the SKPoint's position, so if you have multiple SKPoints at (0, 0), for example, it will return the first one at that position.
Luckily, I should never be in the situation for my use case.

Removing key from map using reflection changes key? Is this a bug?

I am trying to remove the same key from two maps using reflection. However, removing it from the first map is causing a change to the key value. Is this WAI or a bug.
Code at (http://play.golang.org/p/MIkFP_Zrxb):
func main() {
m1 := map[string]bool{"a": true, "b": true}
m2 := map[string]bool{"a": true, "b": true}
fmt.Println(m1)
v1 := reflect.ValueOf(m1)
k := v1.MapKeys()[0]
fmt.Println("KEY BEFORE", k)
v1.SetMapIndex(k, reflect.Value{}) // COMMENT THIS OUT
fmt.Println("m1:", m1)
fmt.Println("KEY AFTER", k)
v2 := reflect.ValueOf(m2)
v2.SetMapIndex(k, reflect.Value{})
fmt.Println("KEY AFTER SECOND CALL", k)
fmt.Println("m2:", m2)
}
produces this output:
map[a:true b:true]
KEY BEFORE a
m1: map[b:true]
KEY AFTER
KEY AFTER SECOND CALL
m2: map[a:true b:true]
Notice that the "a" value is not removed from m2. Commenting out the indicated line causes the call to v2.SetMapIndex to work.
Also notice that the value of "k" changes after the call to SetMapIndex. That appears to be the reason that SetMapIndex isn't working. Can anyone offer an explanation? Is this a bug? Any suggested workaround?
Thanks.
I think it's a bug? The documentation for reflect.SetMapIndex states that "If val is the zero Value, SetMapIndex deletes the key from the map." So it seems that what's happening is the key is getting deleted by the map out from under the reflection type? It's worth noting that even after the deletion, k is still a string:
fmt.Println(k.Kind())
fmt.Println(k.Len())
Output:
string
0
I filed a bug: https://code.google.com/p/go/issues/detail?id=7896
It's fixed in the tip, but hasn't propagated out to the stable release.
The workaround for this is to structure the code so that the map which is the source of the key is the last map from which it's deleted. (I.e., reversing the calls to SetMapIndex() in the original post will behave as expected.
The call to SetMapIndex will touch the complete key/value pair during the remove operation.
From a conceptual point of view this makes sense to me. When deleting a key/value pair from a map there shouldn't be a guarantee that the key stays intact.
Not sure what you are trying to achieve but might use k2 := v2.MapKeys()[0] to delete from map v2. But as suggested don't use reflections for things like this. It is far better to use e.g. the built in delete function.
You also might want to look at the sources to understand the raw details:
http://golang.org/src/pkg/reflect/value.go
http://golang.org/src/pkg/runtime/hashmap.c
Some details on map internals

ODBC: SQLSetConnectAttr actual attribute constant name

At the moment I encountered SQLSetConnectAttrW call with attribute constant equal to either 0 or 1(SQLSetConnectAttrW(0x1231231, 0, 0, -6)). And so I cannot distinguish what is actual SQL_ATTR_* define name so that I can refer to it further. I tried to look through ODBC header files, but ended up with no success in finding what this could be. So my question is what are these constants names?
PS: ADO internally makes this sort of call and I have to figure out what is this being made for.
Best regards, Alexander Chernyaev.
If you are seeing SQLSetConnectAttr(0xNNNNNNNN, 0, 0, -6) then the first argument is a connection handle (a pointer), the second is the attribute to set (I'm not aware of an attribute of value 0), the 3rd is irrelevant and the 4th is SQL_IS_INTEGER implying it is a numeric attribute. Are you sure it is attempting to set attribute 0? Where did you get that information from?
These two attributes are SQL_ATTR_MAX_ROWS and SQL_ATTR_QUERY_TIMEOUT and it's ok to pass them to connection handle as #bohica stated before.

renumbering ordered session variables when deleting one

I'm updating a classic ASP application, written in jScript, for a local pita restaurant. I've created a new mobile-specific version of their desktop site, which allows ordering for delivery and lots of customization of the final pita (imagine a website for Subway, which would allow you to add pickles, lettuce, etc.). Each pita is stored as a string of numbers in a session variable. The total number of pitas is also stored. The session might look like this:
PitaCount = 3
MyPita1 = "35,23,16,231,12"
MyPita2 = "24,23,111,52,12,23,93"
MyPita3 = "115,24"
I know there may be better ways to store the data, but for now, since the whole thing is written, working , and live (and the client is happy), I'd like to just solve the problem I have. Here's the problem...
I've got buttons on the order recap page which allow the customer to delete pitas from the cart. When I do this, I want to renumber the session variables. If the customer deletes MyPita1, I need to renumber MyPita2 to MyPita1, renumber MyPita3 to MyPita2, and then decrement the PitaCount.
The AJAX button sends an integer to an ASP file with the number of the pita to be deleted (DeleteID). My function looks at PitaCount and DeleteID. If they're both 1, it just abandons the session. If they're both the same, but greater than one, we're deleting the most recently added pita, so no renumbering is needed. However, if PitaCount is greater then DeleteID, we need to renumber the pitas. Here's the code I'm using to do that:
for (y=DeleteID;y<PitaCount;y++) {
Session("MyPita" + y) = String(Session.Contents("MyPita" + (y+1)));
};
Session.Contents.Remove("MyPita" + PitaCount);
PitaCount--;
Session.Contents("PitaCount") = PitaCount;
This works for every pita EXCEPT the one which replaces the deleted one, which returns 'undefined'. For example, if I have 6 pitas in my cart, and I delete MyPita2, I end up with 5 pitas in the cart. Number 1, 3, 4, and 5 are exactly what you'd expect, but MyPita2 returns undefined.
I also tried a WHILE loop instead:
while (DeleteID < PitaCount) {
Session("MyPita" + DeleteID) = String(Session.Contents("MyPita" + (DeleteID+1)));
DeleteID++;
};
Session.Contents.Remove("MyPita" + PitaCount);
PitaCount--;
Session.Contents("PitaCount") = PitaCount;
This also returns 'undefined', just like the one above.
Until I can get this working I'm simply writing the most recent pita into the spot vacated by the deleted pita, but this reorders the cart, and I consider that a usability problem because people expect the items they added to the cart to remain in the same order. (Yes, I could add some kind of timestamp to the sessions and order using that, but it would be quicker to fix the problem I'm having, I think).
I'm baffled. Why (using the 6 pita example above) would it work perfectly on the second, third, and fourth iteration through the loop, but not on the first?
I can't be sure, but I think your issue may be that the value of DeleteID is a string. This could happen you assign its value by doing something like:
var DeleteID = Session("DeleteID");
Assuming this is true, then in the first iteration of your loop (which writes to the deleted spot), y is a string, and the expression y+1 is interpreted as a string concatenation instead of a numeric addition. If, for example, you delete ID 1, you're actually copying the value from id 11 ("1" + 1) into the deleted spot, which probably doesn't exist in your tests. This can be tested by adding at least 11 items to your cart and then deleting the first one. On the next iteration, the increment operator ++ forces y to be a number, so the script works as expected from that point on.
The solution is to convert DeleteID to a number when initializing your loop:
for (y = +DeleteID; y < PitaCount; y++) {
There may be better ways to convert a string to a number, but the + is what I remember.

Resources