calling a class/table method in WinSQL - intersystems-cache

new to Cache so please forgive me,
I'm trying to call a class/table method in WinSQL. Basically trying to go select table_methodname() but it says it's not finding the stored function.
In Cache SQL there seems to be either a result set stored procedure which acts like a normal T-SQL stored proc or a class/table method (stored function) that acts like a function.. those are the ones I'm having trouble calling in WinSQL..
thanks!

In order to call a ClassMethod from SQL, you must mark the ClassMethod with the [SqlProc] modifier.
ClassMethod MyMethod() As %Integer [SqlProc]
{
...
}
Then, you can call it with
SELECT MySchema.MyClass_MyMethod()
Documentation is here:
http://docs.intersystems.com/ens20141/csp/docbook/DocBook.UI.Page.cls?KEY=ROBJ_method_sqlproc

Related

How to use recursive_update

I just started to use DBx::Class and begun slightly to understand, but it's complex.
I want to call "recursive_update" but I was not able to manage how I can use it.
If I understand the documentation right, I have to include it in the .../My/Schema.pm which was create by DBIx::Class::Schema::Loader?
__PACKAGE__->load_namespaces(default_resultset_class => '+DBIx::Class::ResultSet::RecursiveUpdate');
When I want to update the data I use the ResultSet with the relationships.
my $result = $schema->resultset('Table')->find($id});
$result->recursive_update({
'rel_table' => [....),
});
unfortunately I got an error:
Can't locate object method "recursive_update" via package My::Schema::Result::Table"
Where is my fault?
recursive_update has to be called on a ResultSet object, not a Result object.
You might want to add a helper method to your Result base class (if you already have one else create it, as it makes sense for many things) which gets a ResultSet restricted to the Result object it is called on and calls recursive_update on it.

Create a function pointer in Game Maker Studio

I would like to dynamically change the script that is executed when a index in an array is called.
The following is valid syntax:
actions[0] = script_do_something
...
actions[n] = script_do_something_else
How do I execute the scripts stored in the array? If I cant, then how else could I replicate a function pointer in GMS?
Unfortunately this doesn't work:
actions[0]()
I would like to avoid if statements as I feel they will get too long and messy.
you should use script_execute function.
script_execute(actions[0]);
also you may pass arguments:
script_execute(actions[0], arg1, arg2);

Constructor that takes a static temp table as input (Progress ABL)

I have a class who's main purpose revolves around a temp table. I want to make a constructor that takes an identical temp table as input.
So far the compiler chokes on any attempt to pass a temp table as a input parameter. If I use a table handle instead, it works. But I'd rather not copy from a dynamic table to a static one.
Progress wants the tables to match up at compile time, but I know they'll be the same - the're defined in a .i file.
Is there an easy way to line up the tables, or am I stuck parsing it out one field at a time?
Works like a charm to me.
CLASS Test.TTOO.TempTableWrapper:
{Test/TTOO/ttCustomer.i}
CONSTRUCTOR PUBLIC TempTableWrapper (TABLE ttCustomer):
FOR EACH ttCustomer:
DISPLAY ttCustomer.CustNum ttCustomer.Name .
END.
END CONSTRUCTOR.
END CLASS.
and the caller:
ROUTINE-LEVEL ON ERROR UNDO, THROW.
USING Test.TTOO.* FROM PROPATH.
DEFINE VARIABLE oWrapper AS TempTableWrapper NO-UNDO .
{Test/TTOO/ttCustomer.i}
/* *************************** Main Block *************************** */
CREATE ttCustomer.
ASSIGN ttCustomer.CustNum = 42
ttCustomer.Name = "It works" .
oWrapper = NEW TempTableWrapper(TABLE ttCustomer ) .
You can also pass the temp-table by-ref:
oWrapper = NEW TempTableWrapper(TABLE ttCustomer BY-REFERENCE) .
However, then the temp-table data is only availalbe during the constructor as BY-REFERENCE calls "overlap" the temp-table within the callee only for the duration of that call.
For permanent "BY-REFERENCE", use the BIND keyword on the call and the paramter - in which case the callee must define the temp-table as REFERENCE-ONLY.
Note, it's not required (although recommended at least by me) to define the temp-tables in include files. At runtime and compile time, the schemas just need to match.
When the compiler does not like your call, delete the classes r-code and recompile.

Setting global variables in working memory in Drools planner

How do I add a global variable to working memory in drools planner's solver to be able to use in scores drool. This is similar to https://issues.jboss.org/browse/JBRULES-2700 but couldn't find a solution though.
What you might be looking for is a #ProblemFactProperty.
Quoting from the documentation:
All objects returned by those [annotated] methods will be inserted into the
ConstraintStreams or Drools session, so the constraint steams or score
rules can access them.
In my own words: You can hold a reference to your global object in your #PlanningSolution class. If you annotate its getter with #ProblemFactProperty you can access it from your drools file.
First some preaching: Using a service (set as a global) to calculate part of the score will break delta based score calculation (read the manual section on that topic), resulting in much less score calculations per second (say 50 instead of 5000 per second on big data sets).
Then a HACK solution: In the StartingSolutionInitializer (soon known as CustomSolverPhaseCommand) do solverScope.getWorkingMemory().setGlobal("key", value).
Then a real, long-term solution: Could you motivate why you need to be able to do this? We can think about adding support for this with something like an optional WorkingMemoryPreperator.
After set the planningProblem:
solver.setPlanningProblem(planningProblem);
You can get access the workingMemory via solutionDirector(HACK) :
DefaultSolutionDirector solutionDirector = ((DefaultSolver)solver).getSolverScope().getSolutionDirector();
solutionDirector.getWorkingMemory().setGlobal("list", new ArrayList<String>());
Cheers!
If you need to use some helper methods in the planner rules, try the following approach which I used in my project:
Create a utility class which includes the helper methods.
Import the utility class in the rule file like importing it in a java class.
Use the helper method in the rule. If you want to use a helper method in the condition, wrap using eval(). If you want to use a helper method in the then part, just use it as normal java method call.
For example, say you have a utility class named PlanningUtil like below:
public class PlanningUtil {
public boolean isGood() {return true;}
public void doSomething() {//...}
}
Then import the utility class in the rule file,
import PlanningUtil;
Use the utility method in the rule
rule "MyRule"
when
eval(PlanningUtil.isGood())
then
PlanningUtil.doSomething(); // note the ';' is a must.
end

MobileSubstrate: MSHookFunction example

I am trying to write a MobileSubstrate plugin which hooks into a C-method. I tried to edit the famous "ExampleHook", by just writing a demo MSHook and hook it in the Initialize method.
This is probably too optimistic and it doesn't work. But I cannot find anywhere a simple example of a MSHookFunction(). There is barely information about this on the Internet. It might be possible I misunderstood the whole concept of MSHookFunction.
Please, can anybody help me out with a little example code? I would deeply appreciate any help.
Best regards,
Marc Backes
I realize you have found this, but I am posting this answer to help whoever else may be needing this.
A simple example can be found at the MobileSubstrate article on the iPhone Dev Wiki, and an actual example of this in a project is at this bit of User Agent Faker.
But what is an answer without an actual explanation? Therefore, here we go!
void MSHookFunction(void* function, void* replacement, void** p_original); is the function definition for MSHookFunction, the magic function which causes your function X() to be interposed by Y(), for instance.
That is, when a program commonly would call X(), the call will be redirected to Y() instead. This is pretty much a basic explanation of function interposing.
Now, what are the parameters, and their usefulness?
function is a function pointer to the function you want to interpose. That would be a function pointer to X(), in our quick explanation.
replacement is a function pointer to the function you want function to be interposed with. In our quick explanation, that would be a function pointer to Y().
p_original is a pointer to a function pointer, which from now on will point to what function used to be.
The reason this is there is simple: If you intend to modify behavior, but not suppress it, you'll still need to call what X() used to be. But a common call to X() wouldn't work as intended, as it would end calling Y() instead of the default function.
Therefore, you have a function pointer to call X() as if it wasn't interposed.
Now, explaining the devwiki example:
static void (*original_CFShow)(CFTypeRef obj); // a function pointer to store the original CFShow().
void replaced_CFShow(CFTypeRef obj) { // our replacement of CFShow().
printf("Calling original CFShow(%p)...", obj);
original_CFShow(obj); // calls the original CFShow.
printf(" done.\n");
}
...
// hook CFShow to our own implementation.
MSHookFunction(CFShow, replaced_CFShow, &original_CFShow);
// From now on any call to CFShow will pass through replaced_CFShow first.
...
CFShow(CFSTR("test"));
Here, we:
Pass a pointer to CFShow, the function we want to change default behavior from as the function parameter.
Pass a pointer to the function we just created, replaced_CFShow as the replacement parameter. That is, whenever CFShow would be called by default, replaced_CFShow will be called instead.
We pass a pointer to the original_CFShow function pointer as the p_original parameter. Since we still want the things CFShow still does by itself to be done inside our replacement function, we call it.