Archive for January, 2011

Facebook? uhm….

Wednesday, January 26th, 2011

So … facebook. Right. Social Network. The all new trendy thing to do. I have to tell you, after seeing all the hi5-like sites here in my country and seeing what kind of people join it and use it I still am pretty reluctant to  using such … “sites”. basically, it’s just a damn dating site with lots of features. The fact that there on your profile along with your personal information you have options for “Interested In: women/men” pretty much proves it.

I won’t get into all the stuff with security, privacy (I hope you know you don’t have privacy there for a lot of stuff. FB application developers know it. You should too, just google). I won’t even say anything about how idiotic the concept is, even if it brings in tons of money (hey, the world is full of idiots) but I will tell you this: the developers there are STUPID.

So, I figured I should create an account. Not because I need or want it but because it makes a pretty damn good launching pad for my stuff (once I get to put it up). As with twitter, I will be doing mostly nothing, just to see if other people “see me” and find me interesting for what I share not because I added them to my “list”.

Ok, so back to why I post this: the developers are idiots. first page, enter email address. So I enter the one I always do: root@ciuly.com no secret there. The error message:  “Please enter a valid email address.”

They are not the first to reject <<root@*>> email addresses but hey, idiots, that IS a valid email address.

so I went with my second choice: ciuly@ciuly.com

Now, the error was “There is an existing account associated with this email.”

You can imagine, I was like WTF???

And indeed, I had an account made.  Seems I made it in december 2009. If I recall correctly, I needed to check out some people 😀 Same reason for which I have a hi5 account lying somewhere.

Anyway, the news is out. There will be some releases coming soon. Keep an eye out 😉

Related posts

Row cannot be located for updating. Some values may have been changed since it was last read.

Thursday, January 13th, 2011

Yet another one of those cryptic messages that basically says “you’re screwed”.

So what was I doing this time? Well, I had my mysql tables designed as having different fields as float. It just came natural to me that way. Everything went well until today when I had to modify that field on a record which had some fractional part (until now I did modifications but only to values with no fractional part) and boom. Took me a while to figure it out that it was the float type of the mysql table field that caused this because you see, float in mysql at least is not exact. It’s an approximation. That means that ADO will have a hard time to find hte modified record if you modify the value with a fractional part. It will actually raise ”

Row cannot be located for updating. Some values may have been changed since it was last read.”

Happy me. Solution? Just change the mysql column float into decimal(M,L). I use Decimal(15,2) as it works fine for my application. Yeah, have a laugh at all those people suggesting cursor type changes, ado property modifications and so on. People, first find THE CAUSE, and then find a way to fix it.

Related posts

Multiple Step Operation Generated Errors – Check each status value

Wednesday, January 12th, 2011

Yet another cryptic error with an unusual/weird test case and solution.

So, my setup:

– a table with a date field marked null/not null (tried both, same thing)

– an TADOTable to work with the above

– added all fields in the field editor

– a TDBDateEdit from RXLib with DefaultToday set to true

You make an append. You don’t touch the date as it’s set for today. You change everything else. You post. And you get the error:

“Multiple Step Operation Generated Errors – Check each status value”

Why? Well, thing is that when you make the append, the underlying TDataSet will set the state of itself to dsInsert, at which point TDBDateEdit will notice that a new record is added and set the date to today which makes the date field to be added to the internal modified field list of the TCustomADODataSet.

Now, the code runs further and calls DoOnNewRecord which clears the above mentioned internal modified field list and hence, when you do post, the date field is not in the list and hence it is not posted.

Now, since on the client side the field is set and has a value, on DB side the field was not sent and is either null or lots of zeros (if field is set not null) and hence they do not match (in this latter case delphi will also error because it cannot convert it to date. Not sure when this is done, but it is done). So, ADO will now raise this error BUT, the record was already added, just with an invalid date value. And if you are in the not null scenario and reload the grid, you will surely get the “ Data provider or other service returned an E_FAIL status.

There you go, yet another scenario for that cryptic error message 🙂

Related posts

Data provider or other service returned an E_FAIL status.

Monday, January 10th, 2011

It just happened. Took me a few minutes to track it down. I’ll be short:

– my steup: mysql and delphi with ADO. a table with a date field set to not null

– on client side, I inserted a record and for some reason did not set the date. that went as lots of zero-s in mysql.

now, when loading that record, I get that message because lots of zeros are not a valid date value.

There you go, another explanation for the dreaded message.

Related posts

Properly refresh DBGrid without loosing current position

Saturday, January 8th, 2011

This article on delphi.about.com shows one way: http://delphi.about.com/od/delphitips2008/qt/dbgrid_row_pos.htm

However, if you consider the following scenario, you’ll notice that one is not working right:

– initial recordset has 10 records

– position on the 9th

– delete first 7 records

– cursor should now be on the 2nd  row.

Same goes if we add records in front of the current record.

So, how to do this correctly? The first impuls is to do something like:


b := ds.GetBookmark;

try

finally

if (b<>nil) and ds.BookMarkValid(b) then

try

ds.GotoBookMark(b);

finally

ds.FreeBookMark(b);

end;

end;

That looks all nice and dandy but:

– this will always position the selected row in the center of the grid. It’s pretty annoying if you do repetitive refreshing (like in a timer)

– if the current record is deleted … nothing happens. Of course if you happen to reposition the cursor (like using locate) in the code, then you will have some random re-positionings. Again, not nice.

So lets start with problem no 2.


RecNo := ds.RecNo;

b := ds.GetBookmark;

try

finally

if (b<>nil) and ds.BookMarkValid(b) then

try

ds.GotoBookMark(b);

finally

ds.FreeBookMark(b);

end

else if (recno<ds.RecordCount) and (recno<>ds.RecNo) then
begin
ds.First;
ds.MoveBy(Max(0, recno-1));
end;

Ok, so this solves the case when the current record is deleted. Still we have to fix the centering of the GotoBookMark.

Now, upon inspection of that function, we see that it actually does a Resync and passes rmCenter to it, which is our problem. So let’s simulate the GotobookMark without centering:


THackDataSet=class(TDataSet) // a nice "hack" so we can access protected members
end;

RecNo := ds.RecNo;

b := ds.GetBookmark;

try

finally

if (b<>nil) and ds.BookMarkValid(b) then

try

//      ds.GotoBookMark(b);

ds.CheckBrowseMode;
THackDataSet(ds).DoBeforeScroll;
THackDataSet(ds).InternalGotoBookmark(b);
ds.Resync([rmExact{, rmCenter}]);
THackDataSet(ds).DoAfterScroll;
finally

ds.FreeBookMark(b);

end

else if (recn<ds.RecordCount) and (recno<>ds.RecNo) then
begin
ds.First;
ds.MoveBy(Max(0, recno-1));
end;

Ok, now this almost solves the problem. Now, the row is repositioned to the last in the grid. Still not what we want. So what we can still do here is force the resync to take the active record the right one and not the one set by the InternalGotoBookmark.


THackDataSet=class(TDataSet) // a nice "hack" so we can access protected members
end;

THackDBGrid=class(TDBGrid)
end;

Row := THackDBGrid(grid).Row;// or THackDataSet(ds).ActiveRecord

RecNo := ds.RecNo;

b := ds.GetBookmark;

try

finally

if (b<>nil) and ds.BookMarkValid(b) then

try

//      ds.GotoBookMark(b);

ds.CheckBrowseMode;
THackDataSet(ds).DoBeforeScroll;
THackDataSet(ds).InternalGotoBookmark(b);
if THackDataSet(ds).ActiveRecord <> Row - 1 then
THackDataSet(ds).MoveBy(Row - THackDataSet(ds).ActiveRecord - 1);
ds.Resync([rmExact{, rmCenter}]);
THackDataSet(ds).DoAfterScroll;
finally

ds.FreeBookMark(b);

end

else if (recno<ds.RecordCount) and (recno<>ds.RecNo) then
begin
ds.First;
ds.MoveBy(Max(0, recno-1));
end;

This is almost perfect. There is still the same issue of positioning on the first/last record when the current record is deleted. I can’t confirm this yet as my test scenarios haven’t gotten that far but I *think* it will happen. And if it does, you can simply apply the same ActiveRecord thing to calculate the correct position for the MoveBy.

I’ll update this post if and when I get to kick this scenario.

http://delphi.about.com/od/delphitips2008/qt/dbgrid_row_pos.htm

Related posts