I am an experienced programmer learning Ruby (and liking it a lot).
I'm working on setting up a database using SQLite3.
In order to better learn Ruby, I'm tracing into SQLite3.
What I don't understand is, where is the code for #new for the Database and Statement classes.
Actually, I expect not a #new method, but a #initialize method.
SQLite3::Database.new(file, options = {})
SQLite3::Statement.new(db, sql)
The above two statements are from the documentation.
But in my code when I try to trace into this
$db = SQLite3::Database.new"MyDBfile"
it just steps over.
Then later on when I try to trace into
#$db.execute
I do get into the #execute method in the Database.rb file, but then it calls the #prepare method where I try to step into
stmt = SQLite3::Statement.new( self, sql )
but again no luck. It just steps over it.
I've scoured the source code, done searches etc but I cannot locate the initialize methods that are being called. Where are they ?
Thank you for considering this question.
The initialize method for SQLite3::Database is implemented in C:
/* call-seq: SQLite3::Database.new(file, options = {})
*
* Create a new Database object that opens the given file. If utf16
* is +true+, the filename is interpreted as a UTF-16 encoded string.
*
* By default, the new database will return result rows as arrays
* (#results_as_hash) and has type translation disabled (#type_translation=).
*/
static VALUE initialize(int argc, VALUE *argv, VALUE self)
Similarly for SQLite3::Statement:
/* call-seq: SQLite3::Statement.new(db, sql)
*
* Create a new statement attached to the given Database instance, and which
* encapsulates the given SQL text. If the text contains more than one
* statement (i.e., separated by semicolons), then the #remainder property
* will be set to the trailing text.
*/
static VALUE initialize(VALUE self, VALUE db, VALUE sql)
The Ruby debugger doesn't know how to step into C functions (assuming the SQLite3 extensions have even been compiled with debugging support) so it skips over them.
Related
I have one Groovy expression. (stored in master table but let's consider it as an individual string for this question)
Example of Groovy expression: if(shortName.equals("do not include")){return false;}; return true;
I want to use it in my oracle SQL query to consider this groovy expression to filter the records. Please note that the shortName is the column of the database table.
I want something like this:
SELECT * FROM MYTABLE
WHERE SOME_FFUNCTION_TO_EVALUATE_GROOVY(<GROOVY_EXPRESSION>);
Thanks in advance.
Perhaps easiest way to do is using javax.script.ScriptEngine and javax.script.ScriptEngineManager classes.
Step 1 : Download the jar files from maven repository for latest stable version of groovy libraries.
https://repo1.maven.org/maven2/org/codehaus/groovy/groovy-all/2.5.10/groovy-all-2.5.10-sources.jar
Step 2 : Load the jar file to schema using loadjava utility. Post import check data dictionary to ensure the java source is loaded to the database to appropriate schema. https://docs.oracle.com/cd/A87860_01/doc/java.817/a81358/02_load3.htm
Step 3: Create java source with a method for groovy expression evaluation.The method accepts string as input and returns 1 if expression evaluates to true and 0 when evaluated to false.This method creates instance of ScriptEngine and calls eval method to evaluate the input expression.
create or replace and resolve java source named
"GroovyEval" as
import java.math.*;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
/**
* Java class to Evaluate Groovy String
*/
public class GroovyEval {
/**
* #param String
* #return 1 if True else 0 if False
*/
public static int evalGroovyExpr(String expr) throws ScriptException{
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("groovy");
Object result = engine.eval(expr);
int lv_output = 0;
if (result.toString().equals("true"))
{
lv_output = 1;
}
if (result.toString().equals("false"))
{
lv_output = 0;
}
return lv_output;
}
};
/
Step 4 : Create a Stored function to call the java source.
create or replace function evaluateGroovyExpr
(n number)
return number
as language java
name 'GroovyEval.evaluateGroovyExpr(String) return int';
/
Step 5: Fire the SQL query to call the function.You might use table columns to build groovy expression, but this is just a demo.
with exprtab as
(select '''do not include''.equals(''do not include'')' expr from dual)
SELECT evaluateGroovyExpr(expr) from exprtab;
Result
1
PS :
Using single quotes to frame the expression will be ideal as that wouldn't confuse JVM.
This is not one solution for all, but works for all expression that evaluates to boolean.
Tips: Idea approach to develop/debug would be to create the class in java and evaluate your expressions and then integrate it to the database.
You can use Eval function in groovy library of java using java stored procedure in DB
A simple example of Eval is given here
The documentation of Eval is given here
If you want to know how to use java stored procedure in oracle DB an example is given here
Also You have to use loadjava to load the groovy library in oracle DB
V8's ObjectTemplate provides us two ways to attach a so-called accessor property to the object under instantiation.
The first one is ObjectTemplate::SetAccessor:
/**
* Sets an accessor on the object template.
*
* Whenever the property with the given name is accessed on objects
* created from this ObjectTemplate the getter and setter callbacks
* are called instead of getting and setting the property directly
* on the JavaScript object.
*
* \param name The name of the property for which an accessor is added.
* \param getter The callback to invoke when getting the property.
* \param setter The callback to invoke when setting the property.
* \param data A piece of data that will be passed to the getter and setter
* callbacks whenever they are invoked.
* \param settings Access control settings for the accessor. This is a bit
* field consisting of one of more of
* DEFAULT = 0, ALL_CAN_READ = 1, or ALL_CAN_WRITE = 2.
* The default is to not allow cross-context access.
* ALL_CAN_READ means that all cross-context reads are allowed.
* ALL_CAN_WRITE means that all cross-context writes are allowed.
* The combination ALL_CAN_READ | ALL_CAN_WRITE can be used to allow all
* cross-context access.
* \param attribute The attributes of the property for which an accessor
* is added.
* \param signature The signature describes valid receivers for the accessor
* and is used to perform implicit instance checks against them. If the
* receiver is incompatible (i.e. is not an instance of the constructor as
* defined by FunctionTemplate::HasInstance()), an implicit TypeError is
* thrown and no callback is invoked.
*/
void SetAccessor(
Local<String> name, AccessorGetterCallback getter,
AccessorSetterCallback setter = nullptr,
Local<Value> data = Local<Value>(), AccessControl settings = DEFAULT, // note the data is on the template level.
PropertyAttribute attribute = None, // not on the instance level.
Local<AccessorSignature> signature = Local<AccessorSignature>(),
SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
and the second one is Template::SetAccessorProperty:
void SetAccessorProperty(
Local<Name> name, // The latter one is called data property.
Local<FunctionTemplate> getter = Local<FunctionTemplate>(),
Local<FunctionTemplate> setter = Local<FunctionTemplate>(),
PropertyAttribute attribute = None,
AccessControl settings = DEFAULT);
Having two very similar APIs confuses me a lot.
Unfortunately there is no docs describing their differences, so I have to do experiment on my own. I found that the combination of Holder() and SetAccessor() will break, while other combinations of Holder() or This() and SetAccessor() or SetAccessorProperty() work fine. On a previous post I ran into this failing combination and was fooled to believe what's went wrong is Holder() or This(). But after the experiment I now believe that it is SetAccessor went wrong.
My question is, whether SetAccessor is a deprecated API? If so, all we have to do is stop using it. If not so, please explain a little bit their differences, esspecially in causing this failure. Many thanks to the warm-hearted and experienced V8 developers!
I agree that the names can be a bit confusing; neither is deprecated. The difference is as follows:
SetAccessor creates a "magic" data property: it looks like a data property to JavaScript (getOwnPropertyDescriptor returns {value: ..., ...}), but when reading/writing the property, the C++ callbacks you specified will be called. For a built-in example, think of Array.prototype.length (where in particular the setter has to do additional work when you use a .length assignment to shorten an array).
SetAccessorProperty creates a regular accessor property, i.e. getOwnPropertyDescriptor returns {get: ..., set: ..., ...}. A built-in example would be Int32Array.prototype.__proto__.byteLength. The name "SetAccessorProperty" reflects the fact that the JS spec calls these properties "accessor properties".
Chances are that in many cases, this difference doesn't matter: interfacing JavaScript code can read and/or write properties either way. But sometimes you might have a reason to care about the distinction, and in that case V8's API gives you that flexibility.
I am working with python and sqlalchemy. I have one table named Team and another named Game. The Game table has columns "away_id" and "home_id" and the Team table has the column "team_id". I just made this hybrid_method for the Team class which will return all game instances where the away_id, or home_id matches the team_id. The argument I pass it, s, is a session instance. How can I write this code as a #hybrid_property where I don't have to pass it a session instance?
#hybrid_method
def games(self, s):
return s.query(Game).filter(or_(Game.away_id==self.team_id, Game.home_id==self.team_id)).all()
First off, from what I can see here this is not a use case for "#hybrid" hybrid is used for specifically the use case where you'd like to say: "MyClass.games == something", at the class level, as well as, "my_object.games == something", at the instance level. That is not the case here, you're trying to run a query in its entirety, passing a specific self.team_id into it - so you need a self, so this is just a regular method or descriptor.
So just use #property with object_session() as the docs say right here:
class MyClass(Base):
# ...
#property
return object_session(self).query(Game).filter(...)
I'm trying to see if there's a way to get a refference of an object which is outside the local (and global) scope, but who exists in memory.
Let's say in my program, i've instantiated an object whose reference is this:
{O:9*\PROGRAM=ZAVG_DELETE_THIS\CLASS=LCL_SMTH}
Far away after tons of calls, in a context where i wouldn't be able to access this object, could i do something like getting the reference of this object simply by knowing the above string?
I was looking into the cl_abap_*descr classes, but i haven't found a method that takes the 'program_name', 'class_name' and 'instance_number', to return the reference of an object.
I'm trying to do this for the purpose of debugging, not to build something that works.
[EDIT 1]:
I assumed that the o:9 string was required in order to get the reference of the object. As pointed out in the response of #mydoghasworms, this isn't the case. It seems that i only need the local name of the variable which holds the reference.
I hope I understand your question correctly, because I am not sure what you mean with "for the purpose of debugging", but here goes:
You can access the variables of another program that are loaded in the memory of the same session (I am pretty sure it does not need to be in the call stack) using:
ASSIGN ('(PROGRAM)VARIABLE') TO LV_LOCAL.
With reference variables, it becomes a bit more tricky, but here is an example that will help to demonstrate.
Here is our calling program that contains a reference variable LR_TEST which we want to access somewhere else. For the purpose of the demonstration, I make reference to a locally defined class (because that's what I gather from your question).
REPORT ZCALLER.
class lcl_test definition.
public section.
data: myval type i.
methods: my_meth exporting e_val type i.
endclass.
data: lr_test type ref to lcl_test.
CREATE OBJECT lr_test.
lr_test->MYVAL = 22.
perform call_me(zcallee).
class lcl_test implementation.
method my_meth.
* Export the attribute myval as param e_val.
e_val = myval.
endmethod.
endclass.
Here is the program in which we want to access a variable from the above program.
REPORT ZCALLEE.
form call_me.
field-symbols: <ref>.
data: ld_test type ref to object.
data: lv_val type i.
* Exhibit A: Gettinf a reference to a 'foreign' object instance
assign ('(ZCALLER)LR_TEST') to <ref>.
* <ref> now contains a reference to the class instance from the program
* ZCALLER (not very useful, except for passing around maybe)
* Exhibit B: Getting a public attribute from a 'foreign' class instance
assign ('(ZCALLER)LR_TEST->MYVAL') to <ref>.
* <ref> now contains the value of the attribute MYVAL
* Exhibit C: Getting a reference to an instance and calling a method
assign ('(ZCALLER)LR_TEST') to <ref>. "Again the class reference
if sy-subrc = 0. "Rule: Always check sy-subrc after assign before
"accessing a field symbol! (but you know that)
ld_test = <ref>. "Now we have a concrete handle
* Now we make a dynamic method call using our instance handle
CALL METHOD ld_test->('MY_METH')
IMPORTING
e_val = lv_val.
endif.
endform.
As you know TCL has some mathematical functions such as sin, cos, and hypot that are called in expr command with () braces as follows:
puts [expr sin(1.57)]
Now how can I add a function using TCL library functions so that it was called exactly the same way, and was doing something that a certain proc defines.
I would like to clarify my question. Say there is a proc (string) as follows:
proc add { a b } { return [expr $a+$b] } ;# string of a proc
Also I have a TCL interpreter in my C++ code. Now I want get the string of a proc and runtime register a function called add into the tcl::mathfunc namespace (I guess I should use Tcl_CreateObjCommand) so that I could call the following:
puts [expr add(1.57, 1.43)]
How this can be done. Could you please write a simple example. I could not find any example in TCL documentation and in books as well which describe the usage of this command.
Creating a function from C isn't too hard. To do it, you've got to write an implementation of a command that will perform the operation, and register that implementation as a command in the correct namespace. (In 8.4 and before, functions were done with a separate interface that was quite a bit nastier to use; the mechanism was wholly overhauled in 8.5.)
Command Implementation
Note that the signature is defined, and the ignored parameter is not used here. (It's really a void * — great when you're wanting to do things like binding a command to an object — but it simply isn't needed for doing an addition.)
static int AddCmd(ClientData ignored, Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]) {
double x, y, sum;
/* First, check number of arguments: command name is objv[0] always */
if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, "x y");
return TCL_ERROR;
}
/* Get our arguments as doubles */
if ( Tcl_GetDoubleFromObj(interp, objv[1], &x) != TCL_OK ||
Tcl_GetDoubleFromObj(interp, objv[2], &y) != TCL_OK) {
return TCL_ERROR;
}
/* Do the real operation */
sum = x + y;
/* Pass the result out */
Tcl_SetObjResult(interp, Tcl_NewDoubleObj(sum));
return TCL_OK;
}
Don't worry about the fact that it's allocating a value here; Tcl's got a very high performance custom memory manager that makes that a cheap operation.
Command Registration
This is done usually inside an initialization function that is registered as part of a Tcl package definition or which is called as part of initialization of the overall application. You can also do it directly if you are calling Tcl_CreateInterp manually. Which you do depends on how exactly how you are integrating with Tcl, and that's quite a large topic of its own. So I'll show how to create an initialization function; that's usually a good start in all scenarios.
int Add_Init(Tcl_Interp *interp) {
/* Use the fully-qualified name */
Tcl_CreateObjCommand(interp, "::tcl::mathfunc::add", AddCmd, NULL, NULL);
return TCL_OK;
}
The first NULL is the value that gets passed through as the first (ClientData) parameter to the implementation. The second is a callback to dispose of the ClientData (or NULL if it needs no action, as here).
Doing all this from C++ is also quite practical, but remember that Tcl is a C library, so they have to be functions (not methods, not without an adapter) and they need C linkage.
To get the body of a procedure from C (or C++), by far the easiest mechanism is to use Tcl_Eval to run a simple script to run info body theCmdName. Procedure implementations are very complex indeed, so the interface to them is purely at the script level (unless you actually entangle yourself far more with Tcl than is really wise).