Apple Event object property hasAlarms returning incorrect boolean value - ffi

I am attempting to wrap a number of EkEventkit objective-c commands using Livecode Builder using its Foreign Function Interface (FFI). I have created a library for use by Livecode Script but when run the Event property "hasAlarms" returns true on events that have no alarm set. The odd thing is that repeat events that were entered into my calendar many years ago and therefore several OS versions ago appear to report correct values.
The FFI definition I am using is
private foreign handler Objc_EventHasAlarms(in pEventObj as objcID) \
returns optional CBool \
binds to "objc:EventKit>EKEvent.hasAlarms"
The code above does not throw any errors so I wonder if I have stumbled across a bug in the Calendar (v11) application running on Big Sur. Any thoughts?

The issue is likely caused by your return value returns optional CBool which should be returns CBool
So:
private foreign handler Objc_EventHasAlarms(in pEventObj as ObjcId) \
returns CBool \
binds to "objc:EventKit>EKCalendarItem.-hasAlarms"
A further suggestion would be to check the result of:
private foreign handler Objc_EventAlarms(in pEventObj as ObjcId) \
returns optional ObjcId \
binds to "objc:EventKit>EKCalendarItem.-alarms"
via:
if Objc_EventAlarms(tCalendarItem) is nothing then
-- no alarms
end if

Related

SQL Server 2012 assembly execution failure - System.NullReferenceException: Object reference not set to an instance of an object

I am trying to execute a UDF which uses a CLR assembly. Each time I try to run it I get the below error:
Msg 6522, Level 16, State 1, Line 45
A .NET Framework error occurred during execution of user-defined routine or aggregate "Geocode":
System.NullReferenceException: Object reference not set to an instance of an object.
at ProSpatial.UserDefinedFunctions.GeocodeUDF(SqlString countryRegion, SqlString adminDistrict, SqlString locality, SqlString postalCode, SqlString addressLine)
It is a geocoding assembly, which is based on the below blog:
https://alastaira.wordpress.com/2012/05/04/geocoding-in-sql-server-with-the-bing-maps-locations-api/
Is there anything I can do to fix it? It was working fine, but just stopped working recently. I changed the Bing Maps key to a new one, but that hasn't resolved the issue. Anyone have any ideas?
Cheers
Edit: I entered a formatted URL into Chrome, to see if I can get the error. I entered the below URL format:
http://dev.virtualearth.net/REST/v1/Locations?countryRegion={0}&adminDistrict={1}&locality={2}&postalCode={3}&addressLine={4}&key={5}&output=xml
All I did was to replace items 0 to 5 with their respective entries. I left the curly brackets in there, and then also tried it without the curly brackets. Without the curly brackets, the URL returned a result with no issues.
In the browser, I am getting geocoded results, but not in SQL any more
Just worked it out. One of the address fields that was being geocoded was null in the database, and the API did not like that. So I removed that from the geocoding list
Looking at the code in that blog, if you are passing in a NULL, then it's not the API that's throwing the error. The error is happening because NULL values are not being handled when the method is first called. The code just casts the SqlString input parameters to string without first checking to see if there is a value in the SqlString variable. SqlString is very similar to a nullable string.
Fortunately, it is rather easy to adjust the code to properly handle NULL values in the input parameters. Starting with a redacted snippet of the original code below, I will show how to do this for one parameter and you can repeat that modification for the others (well, the ones that might actually be NULL in the DB; no need to do this for parameters that are guaranteed to be there due to being in a NOT NULL column).
public static SqlGeography GeocodeUDF(
SqlString countryRegion,
SqlString adminDistrict,
SqlString locality,
SqlString postalCode,
SqlString addressLine
)
{
...
string localAdminDistrict = string.Empty;
if (!adminDistrict.IsNull)
{
localAdminDistrict = adminDistrict.Value;
}
// Attempt to geocode the requested address
try
{
geocodeResponse = Geocode(
(string)countryRegion,
localAdminDistrict,
(string)locality,
(string)postalCode,
(string)addressLine
);
}
All I did was:
Added a local variable for localAdminDistrict, defaulted to an empty string.
Added an if block to set localAdminDistrict if adminDistrict is not null.
Updated the call to Geocode() to use localAdminDistrict instead of (string)adminDistrict.
This should work as long as the Bing Maps API is ok with an empty value for adminDistrict (i.e. ...&adminDistrict=&locality=... ), as opposed to adminDistrict not being present in the GET request (which is easy enough, it just requires an additional modification).
ALSO: As long as you are going to be in there updating the code, you really should move the calls to the Close() and Dispose() methods into a finally block for that try / catch.
For more info on working with SQLCLR in general, please visit: SQLCLR Info

How to call a function with void return using Firedac FDConnection Component in Delphi XE5?

I recently started using the [ExecSQLScalar]1 and [ExecSQL]2 methods of the FDConnection component in Delphi XE5. It's very handy not to need to build a Dataset object, like FDQuery just for simple queries or executions.
However I had a curious problem when executing a function with void return that has internal validations where it can generate exceptions. I'm using a Postgres database.
CREATE FUNCTION can_be_exception()
RETURNS void AS
$$
BEGIN
RAISE EXCEPTION E'fail';
END;
$$
LANGUAGE plpgsql STABLE;
In delphi, I call the ExecSQLScalar function ...
FDConnection1.ExecSQLScalar('select 1');
FDConnection1.ExecSQLScalar('select can_be_exception()');
On first run, I get the following error:
Project TFDConnectionDEMO.exe raised exception class
EPgNativeException with message '[FireDAC][Phys][PG][libpq] ERROR:
fail'.
On the second run, I get a Violation Access error:
Project TFDConnectionDEMO.exe raised exception class $C0000005 with
message 'access violation at 0x00000000: read of address 0x00000000'.
Apparently the error occurs in the line below in unit FireDAC.Comp.Client
function TFDCustomConnection.ExecSQLScalar(const ASQL: String;
const AParams: array of Variant; const ATypes: array of TFieldType): Variant;
var
oCmd: IFDPhysCommand;
begin
oCmd := BaseCreateSQL;
try
if BasePrepareSQL(oCmd, ASQL, AParams, ATypes) or (FExecSQLTab = nil) then begin
FDFree(FExecSQLTab);
...
ignoring the previous error and trying again, another error is displayed...
Project TZConnectionDEMO.exe raised exception class EFDException with
message '[FireDAC][DatS]-24. Row is not nested'.
Searching, I found no response to this error. I figured my mistake would be to call the bank raise_exception function using the ExecSQLScalar function of the FDConnection component. So I tried using FDConnection.ExecSQL and as I imagined, you can not use this if there is a SELECT clause in the parameter.
Is there a better way to call function with void return using FDConnection.ExecSQL? would a BUG be in the component? or would not it be correct to make that kind of call?
Using ExecSQLScalar is fine in this case. This is certainly a bug (which was already fixed, at least in Delphi 10.2.3). As you've correctly pointed out, the problem is in releasing a table storage object instance held by the FExecSQLTab field by using FDFree procedure.
I don't have Delphi XE5 source code but maybe you can see something like this inside (comments about what happened are added by me):
if BasePrepareSQL(oCmd, ASQL, AParams, ATypes) or (FExecSQLTab = nil) then
begin
FDFree(FExecSQLTab); { ← directly calls destructor if object is not nil }
FExecSQLTab := oCmd.Define; { ← no assignment if command execution raises exception }
end;
Problem was that when a SQL command execution raised exception during storage table definition stage (oCmd.Define), reference to previously destroyed storage table object instance (by FDFree) remained stored in the FExecSQLTab field (as a dangling pointer).
Then when a different command was executed that way, FDFree procedure was called just for that dangling pointer. Hence the access violation.
Way to correct this is replacing line e.g. by:
FDFree(FExecSQLTab);
by:
FDFreeAndNil(FExecSQLTab);
which was done in some later Delphi release.

Two arrayCollection. Only one is an ArrayCollection [duplicate]

since 2 weeks, we are having this problem while trying to flush new elements:
CRITICAL: Doctrine\ORM\ORMInvalidArgumentException:
A new entity was found through the relationship 'Comment#capture' that was not configured to cascade persist operations for entity
But the capture is already in the database, and we are getting it by a findOneBy, so if we cascade persist it, or persist it, we get a
Table constraint violation: duplicate entry.
The comments are created in a loop with differents captures, with a new, and all required field are set.
With all of the entities persisted and / or got by a findOne (and all valid), the flush still fails.
I'm on this issue since a while, so please help me
I had the same problem and it was the same EntityManager. I wanted to insert an object related ManyToOne. And I don't want a cascade persist.
Example :
$category = $em->find("Category", 10);
$product = new Product();
$product->setCategory($category)
$em->persist($product);
$em->flush();
This throws the same exception for me.
So the solution is :
$category = $em->find("Category", 10);
$product = new Product();
$product->setCategory($category)
$em->merge($product);
$em->flush();
In my case a too early call of
$this->entityManager->clear();
caused the problem. It also disappeared by only doing a clear on the recent object, like
$this->entityManager->clear($capture);
My answer is relevant for topic, but not very relevant for your particular case, so for those googling I post this, as the answers above did not help me.
In my case, I had the same error with batch-processing entities that had a relation and that relation was set to the very same entity.
WHAT I DID WRONG:
When I did $this->entityManager->clear(); while processing batch of entities I would get this error, because next batch of entities would point to the detached related entity.
WHAT WENT WRONG:
I did not know that $this->entityManager->clear(); works the same as $this->entityManager->detach($entity); only detaches ALL of the repositorie`s entities.
I thought that $this->entityManager->clear(); also detaches related entities.
WHAT I SHOULD HAVE DONE:
I should have iterated over entities and detach them one by one - that would not detach the related entity that the future entities pointed to.
I hope this helps someone.
First of all, you should take better care of your code, I see like 3 differents indentations in your entity and controller - this is hard to read, and do not fit the Symfony2 coding standards.
The code you show for your controller is not complete, we have no idea from where $this->activeCapture is coming. Inside you have a $people['capture'] which contains a Capture object I presume. This is very important.
If the Capture in $people['capture'] is persisted / fetched from another EntityManager than $this->entityManager (which, again, we do not know from where it come), Doctrine2 have no idea that the object is already persisted.
You should make sure to use the same instance of the Doctrine Entity Manager for all those operations (use spl_object_hash on the EM object to make sure they are the same instance).
You can also tell the EntityManager what to do with the Capture object.
// Refreshes the persistent state of an entity from the database
$this->entityManager->refresh($captureEntity);
// Or
// Merges the state of a detached entity into the
// persistence context of this EntityManager and returns the managed copy of the entity.
$captureEntity = $this->entityManager->merge($captureEntity);
If this does not help, you should provide more code.
The error:
'Comment#capture' that was not configured to cascade persist operations for entity
The problem:
/**
* #ORM\ManyToOne(targetEntity="Capture", inversedBy="comments")
* #ORM\JoinColumn(name="capture_id", referencedColumnName="id",nullable=true)
*/
protected $capture;
dont configured the cascade persist
try with this:
/**
* #ORM\ManyToOne(targetEntity="Capture", inversedBy="comments", cascade={"persist", "remove" })
* #ORM\JoinColumn(name="capture_id", referencedColumnName="id",nullable=true)
*/
protected $capture;
Refreshing the entity in question helped my case.
/* $item->getProduct() is already set */
/* Add these 3 lines anyway */
$id = $item->getProduct()->getId();
$reference = $this->getDoctrine()->getReference(Product::class, $id);
$item->setProduct($reference);
/* Original code as follows */
$quote->getItems()->add($item);
$this->getDoctrine()->persist($quote);
$this->getDoctrine()->flush();
Despite my $item already having a Product set elsewhere, I was still getting the error.
Turns out it was set via a different instance of EntityManager.
So this is a hack of sorts, by retrieving id of the existing product, and then retrieving a reference of it, and using setProduct to "refresh" the whatever connection. I later fixed it by ensuring I have and use only a single instance of EntityManager in my codebase.
I got this error too when tried to add new entity.
A new entity was found through the relationship 'Application\Entity\User#chats'
that was not configured to cascade persist operations for entity: ###.
To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or
configure cascade persist this association in the mapping for example #ManyToOne(..,cascade={"persist"}).
My case was that I tried to save entity, that shouldn't be saved. Entity relations was filled and tried to be saved (User has Chat in Many2Many, but Chat was a temporary entity), but there were some collisions.
So If I use cascade={"persist"} I get unwanted behaviour - trash entity is saved. My solution was to remove non-saving entity out of any saving entities:
// User entity code
public function removeFromChats(Chat $c = null){
if ($c and $this->chats->contains($c)) {
$this->chats->removeElement($c);
}
}
Saving code
/* some code witch $chat entity */
$chat->addUser($user);
// saving
$user->removeFromChats($chat);
$this->getEntityManager()->persist($user);
$this->getEntityManager()->flush();
I want to tell about my case as that might be helpful to somebody.
Given two entities: AdSet and AdSetPlacemnt. AdSet has the following property:
/**
* #ORM\OneToOne(targetEntity="AdSetPlacement", mappedBy="adSet", cascade={"persist"})
*
* #JMS\Expose
*/
protected $placement;
Then error appears when I try to delete some AdSet objects in a cycle after 1st iteration
foreach($adSetIds as $adSetId) {
/** #var AdSet $adSet */
$adSet = $this->adSetRepository->findOneBy(["id" => $adSetId]);
$this->em->remove($adSet);
$this->em->flush();
}
Error
A new entity was found through the relationship 'AppBundle\Entity\AdSetPlacement#adSet' that was not configured to cascade persist operations for entity: AppBundle\Entity\AdSet#00000000117d7c930000000054c81ae1. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example #ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'AppBundle\Entity\AdSet#__toString()' to get a clue.
Solution
The solution was to add "remove" to $placement cascade options to be:
cascade={"persist","remove"}. This guarantees that Placement also becomes detached. Entity manager will "forget" about Placement object thinking of it as "removed" once AdSet is removed.
Bad alternative
When trying to figure out what's going on I've seen a couple answers or recommendations to simply use entity manager's clear method to completely clear persistence context.
foreach($adSetIds as $adSetId) {
/** #var AdSet $adSet */
$adSet = $this->adSetRepository->findOneBy(["id" => $adSetId]);
$this->em->remove($adSet);
$this->em->flush();
$this->em->clear();
}
So that code also works, the issue gets solved but it's not always what you really wanna do. Indeed it's happens quite rarely that you actually need to clear entity manager.

Gtk signal with multiple arguments

Context
After writing a simple application using a GtkEntry widget to process textual commands from user I would like to do some design changes.
As of now I use signal hook on key-press. If key(s) are a specified value, then show command line and process various actions on entry widget. Like e.g.
Ctrl+a: move cursor to start of input.
Ctrl+u: delete text before the cursor.
...
As well as parsing commands and saving/loading history.
I am not satisfied with how this is stitched together. The command parsing becomes a subset of:
main_window -> mode_check -> command_line_act -> parse_cmd+execute
As I see it one good approach would be to write a new widget using GtkEntry as base – and send signals on command enter. All of the internals like Ctrl+... and history handled by the new widget.
Signals emitted from new widget being e.g.:
"cmdline-abort"
"cmdline-cmd"
...
Status
Have written the base for this but I am at a hault when it comes to emitting signals with more then one argument.
I have:
gtk_signal_emit(obj, sig, 0, command)
|
+---- string.
but would like, (for now at least, most likely more/other down the line.):
gtk_signal_emit(obj, sig, 0, command, length)
gtk_emit_signal Typo fixed. Thanks to jku.. Also, now using g_signal_
In widget code:
static void
cmdline_class_init(CmdlineClass *klass)
{
With one argument I am using g_signal_new() as:
cmdline_signals[CMDLINE_CMD] = g_signal_new(
"cmdline-cmd",
G_TYPE_FROM_CLASS(klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET(CmdlineClass, cmdline),
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
1,
G_TYPE_STRING
);
And as I see it, for two arguments, should change it to something like:
cmdline_signals[CMDLINE_CMD] = g_signal_new(
"cmdline-cmd",
G_TYPE_FROM_CLASS(klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET(CmdlineClass, cmdline),
NULL,
NULL,
g_cclosure_user_marshal_VOID__STRING_INT,
G_TYPE_NONE,
2,
G_TYPE_STRING,
G_TYPE_INT
);
Trouble in the garden
Using glib-genmarshal to generate marshals with marshal.list holding:
VOID:STRING,INT
This works, but gives me a warning upon compile time as:
warning: ISO C forbids conversion of object pointer to function pointer type
Caused by this code generated by glib-genmarshal:
typedef void (*GMarshalFunc_VOID__STRING_INT) (gpointer data1,
gpointer arg_1,
gint arg_2,
gpointer data2);
register GMarshalFunc_VOID__STRING_INT callback;
/* GCC Warnig: conversion of object pointer to function => */
callback = (GMarshalFunc_VOID__STRING_INT) (
marshal_data ?
marshal_data :
cc->callback
);
Question
Is this the wrong approach? Is there some way to fix the conversion error? Etc.
As a note: I am fairly new to Gtk, and Gui programming in general.
Side point
There are some deprecations I also wonder if could affect the code / should be avoided:
GtkSignalMarshaller, does this indicate anything about the status of GSignalCMarshaller?
GtkCallbackMarshal, does this indicate anything about the use of marshalers in general?
This warning does appear (with -pedantic) on some signal marshalling code, and not just in your code. As far as I can see you are not doing anything wrong though -- except for using gtk_signal_emit() (I assume you meant that and not gtk_emit_signal() which does not exist as far as I know): you should not use any gtk_signal-prefixed code: that stuff is all deprecated. See the reference for details. Use GObject instead: g_signal_emit() or g_signal_emit_by_name() should work for you.
The signal marshaller deprecations you mention are about this same thing: GObject handles everything related to this now (and has for a long time already).
As practical advice: Often adding things to signal signatures is not worth the trouble, and this might be the case for you as well: maybe your signal does not need the command string at all, and the signal handler could just query it with your_object_get_command()?
Practical advice #2: Consider using GTK+ 3 for new code. Not having all that deprecated stuff around confusing everyone is just lovely.

JDO for GAE: Update objects returned by a query

There is persistable class Project, each instance of which has list of objects of Version type (owned one-to-many relation between Project and Version classes).
I'm getting several Version objects from datastore with query, change them and try to save:
PersistenceManager pm = PMF.get().getPersistenceManager();
Transaction tx = pm.currentTransaction();
try {
tx.begin();
Query q = pm.newQuery(Version.class, "... filters here ...");
q.declareParameters(" ... parameters here ...");
List<Version> versions = (List<Version>)q.execute(... parameters here ...);
if (versions.size() > 0) {
for (Version version : versions) {
version.setOrder(... value here ...);
}
pm.makePersistentAll(versions);
}
tx.commit();
return newVersion.toVersionInfo();
} finally {
pm.close();
}
Everything is executed without errors, query actually returns several objects, properties are set correctly in runtime versions list, but objects properties are not updated in datastore.
Generally, as far as I understand, versions should be saved even without calling
pm.makePersistentAll(versions);
, since object properties are set before pm.close(), but nothing is saved, if this row is omitted, as well.
At the same time, if I retrieve instance of type Project (which owns many instances of type Version) with pm.getObjectById() method, and walk through all related Version objects in the loop, all changes are saved correctly (without calling pm.makePersistent() method).
The question is, what's wrong with such way of updating objects? Why Version object properties are not updated in datastore?
I could not find anything helpful neither in JDO nor in GAE documentation.
Thanks for advice about logs from DataNucleus and sympathy from Peter Recore :)
Frankly, I missed few important points in my question.
Actually,between
tx.begin();
and
Query q = pm.newQuery(Version.class, "... filters here ...");
I am retrieving Project instance, and after Version instances updating loop I am persisting some one more Version object.
So, I actually retrieved some of versions list twice, and according to committing order in logs, Project instance was saved twice, as well. The second save operation overwritten the first one.
I changed the order of operations, and got expected behavior.

Resources