Custom ARQ function not working with fuseki endpoint - function

I successfully implemented sparql queries using custom ARQ functions using the following (custom function code):
public class LevenshteinFilter extends FunctionBase2 {
public LevenshteinFilter() { super() ; }
public NodeValue exec(NodeValue value1, NodeValue value2){
LevenshteinDistance LD=new LevenshteinDistance();
int i = LD.apply(value1.asString(), value2.asString());
return NodeValue.makeInteger(i);
}
}
it works fine when I query against a Model loaded from a turtle file, like this:
InputStream input = QueryProcessor.class.getClassLoader().getResourceAsStream("full.ttl");
model = ModelFactory.createMemModelMaker().createModel("default");
model.read(input,null,"TURTLE"); // null base URI, since model URIs are absolute
input.close();
with the query being sent like this :
String functionUri = "http://www.example1.org/LevenshteinFunction";
FunctionRegistry.get().put(functionUri , LevenshteinFilter.class);
String s = "whatever you want";
String sparql = prefixes+" SELECT DISTINCT ?l WHERE { ?x rdfs:label ?l . " + "FILTER(fct:LevenshteinFunction(?l, \"" + s + "\") < 4) }";
Query query = QueryFactory.create(sparql);
QueryExecution qexec = QueryExecutionFactory.create(query, model);
ResultSet rs = qexec.execSelect();
However, if i use a working fuseki endpoint for the same dataset (full.ttl) like this :
fusekiUrl="http://localhost:3030/ds/query";
sending the query like this (using QueryExecutionFactory.sparqlService(fusekiUrl,query) instead of QueryExecutionFactory.create(query,model) ):
String functionUri = "http://www.example1.org/LevenshteinFunction";
FunctionRegistry.get().put(functionUri , LevenshteinFilter.class);
String s = "whatever you want";
String sparql = prefixes+" SELECT DISTINCT ?l WHERE { ?x rdfs:label ?l . " + "FILTER(fct:LevenshteinFunction(?l, \"" + s + "\") < 4) }";
Query query = QueryFactory.create(sparql);
QueryExecution qexec = QueryExecutionFactory.sparqlService(fusekiUrl,query);
ResultSet rs = qexec.execSelect();
Then I don't get any results back. In both cases I printed out the FunctionRegistry and they contain exactly the same entries, especially :
key=http://www.example1.org/LevenshteinFunction
value: org.apache.jena.sparql.function.FunctionFactoryAuto#5a45133e
Any clue ?
Thanks
Back on that question that I finally solved. There was several issues, one which is the fact that (obviously !!) Remote endpoint and client are running on different jvms.
To get the thing working, do the following (for a stupid MyFilter custom function - i.e strlen) :
1) Deploy the custom functions classes jar on fuseki server
2) Modify the fuseki config :
add [] ja:loadClass "my.functions.package.MyFilter"
where MyFilter implementation is :
import org.apache.jena.sparql.expr.NodeValue;
import org.apache.jena.sparql.function.FunctionBase1;
public class MyFilter extends FunctionBase1 {
public MyFilter() { super() ; }
public NodeValue exec(NodeValue value1){
int d = value1.asString().length();
return NodeValue.makeInteger(new Integer(d));
}
}
3) add the following prefix to the context:
PREFIX f: <java:my.functions.package.>
Note that "my.functions.package." is the package of MyFilter
class, not the class itself --> this means that you never call a class
method in sparql queries but only a class that implements
org.apache.jena.sparql.function.FunctionBaseX where X is the number of
argument of your filter function
4) Write (for instance) the query like this:
SELECT DISTINCT ?l
WHERE { ?x skos:prefLabel ?l .
FILTER (f:MyFilter(?l) < 20)
}
EDIT: step 2) is not necessary

Related

C sharp Dapper ms access query like parameters

I have a list of parameters : numericPartList : 029%, 035% for example.
As mentioned in the code, with only 1 parameter it works, but more, no...
public static List<tLicencie> GetDepartement(List<string> numericPartList)
{
ConnectionStringSettings connex = ConfigurationManager.ConnectionStrings["MaConnection"];
string connString = connex.ProviderName + connex.ConnectionString;
using (OleDbConnection con = new OleDbConnection(connString))
{
string sql;
if (numericPartList.Count < 2)
{
sql = "select * from tLicencie where NOCLUB like #numericPartList "; // Works !
}
else
{
sql = "select * from tLicencie where NOCLUB like #numericPartList "; // Does not Work
}
return (List<tLicencie>)con.Query<tLicencie>(sql, new { numericPartList });
}
}
I get an error message :
Syntax error (comma) in expression 'NOCLUB like (# numericPartList1, # numericPartList2)'. "
How to solve this problem?
A solution for the moment: I add DapperExtentions then
var pga = new PredicateGroup { Operator = GroupOperator.Or, Predicates = new List<IPredicate>() };
pga.Predicates.Add(Predicates.Field<tLicencie>(f => f.NOCLUB, Operator.Like, "029%"));
pga.Predicates.Add(Predicates.Field<tLicencie>(f => f.NOCLUB, Operator.Like, "035%"));
IEnumerable<tLicencie> list = con.GetList<tLicencie>(pga);
The dapper list expansion is only intended for use with in, i.e. it would expand:
where foo in #x
to
where foo in (#x0, #x1, #x2)
(or some other variants, depending on the scenario).
It cannot be used with like in this way, as it will give invalid SQL; you would need to compose your SQL and parameters in a more manual fashion, perhaps using DynamicParameters which works more like a dictionary; i.e. you would need to loop in such a way as to construct
where (foo like #x0 or foo like #x1 or foo like #x2)

how to put % in string

I have tried using '%%' and '%' already, none of these working in the below scenario.
The output of query is:
UPPER('field') LIKE UPPER('string')
But I want the output as:
UPPER('field') LIKE UPPER('%string%')
You're trying to combine a Lookup and a Transform in the same query. You can only do one at a time. This is because Lookup automatically adds parentheses around lhs_params and rhs_params.
When you tried return 'UPPER(%s) LIKE UPPER(%%%s%%)' % (lhs, rhs), params this is what caused the unsupported character error.
You need to construct your Bilateral Transformer to convert both sides to uppercase separately from your lookup function.
Really what you want is to use the Transform from the docs combined with __contains which replaces your LIKE Lookup:
from django.db.models import Transform
class UpperCase(Transform):
lookup_name = 'upper'
function = 'UPPER'
bilateral = True
Your query would be:
YourObject.objects.filter(yourvalue__upper__contains="something")
You can override process_rhs method and modify the value there:
class MyCustomLookup(Lookup):
lookup_name = 'custom_lookuptest'
def as_sql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params
return 'UPPER(%s) LIKE UPPER(%s)' % (lhs, rhs), params
def process_rhs(self, compiler, connection):
value = '%%%s%%' % self.rhs
if self.bilateral_transforms:
if self.rhs_is_direct_value():
value = Value(value, output_field=self.lhs.output_field)
value = self.apply_bilateral_transforms(value)
value = value.resolve_expression(compiler.query)
if hasattr(value, 'get_compiler'):
value = value.get_compiler(connection=connection)
if hasattr(value, 'as_sql'):
sql, params = compiler.compile(value)
return '(' + sql + ')', params
if hasattr(value, '_as_sql'):
sql, params = value._as_sql(connection=connection)
return '(' + sql + ')', params
else:
return self.get_db_prep_lookup(value, connection)

Load 3D model in Unity using Resource folder and Mysql

I want to load 3D model using Resource folder. I created an sql database to store the address. In this case I stored the file "deer-3ds" in folder "Models" and also save these information in a table named "modeladdress" in sql.
So please help me to correct my code. I know that it's 100% wrong but I dont know how to fix it. Thank you.
using UnityEngine;
using System.Collections;
using System;
using System.Data;
using Mono.Data.Sqlite;
public class addobject : MonoBehaviour {
// Use this for initialization
void Start () {
//GameObject deer=Instantiate(Resources.Load("deer-3d.bak",typeof(GameObject)))as GameObject;
// GameObject instance = Instantiate(Resources.Load("Models/deer-3ds", typeof(GameObject))) as GameObject;
string conn = "URI=file:" + Application.dataPath + "/modeladdress.s3db"; //Path to database.
IDbConnection dbconn;
dbconn = (IDbConnection) new SqliteConnection(conn);
dbconn.Open(); //Open connection to the database.
IDbCommand dbcmd = dbconn.CreateCommand();
string sqlQuery = "SELECT ordinary,foldername, filename " + "FROM modeladdress";
dbcmd.CommandText = sqlQuery;
IDataReader reader = dbcmd.ExecuteReader();
while (reader.Read ()) {
int ordinary = reader.GetInt32 (0);
string foldername = reader.GetString (1);
string filename = reader.GetString (2);
string path = foldername + "/" + filename;
//Debug.Log( "value= "+value+" name ="+name+" random ="+ rand);
GameObject instance = Instantiate(Resources.Load(path, typeof(GameObject))) as GameObject;
instance.SetActive (true);
}
reader.Close();
reader = null;
dbcmd.Dispose();
dbcmd = null;
dbconn.Close();
dbconn = null;
}
// Update is called once per frame
void Update () {
// GameObject instance = Instantiate(Resources.Load("Models/deer-3ds", typeof(GameObject))) as GameObject;
// instance.SetActive (true);
}
}
First of all, you are using SQLite at your database management system, not MySQL. Second, the way you have written your query,
string sqlQuery = "SELECT ordinary,foldername, filename " + "FROM modeladdress";
Will return the ordinary, foldername, and filename for every model. You need to use a WHERE clause to specify precisely which model you want to use. Thus, you need some way to know which model you want to query from the database before you actually execute the query, and in that case, why even query a database? You're going to have to store some unique identifier anyway so a database solves nothing.
Now concerning the actual code you have written, it appears to be correct (i.e. it should be returning what you want). The problem must be that either your table is empty, your values that are returned are incorrect, or that the object is being instantiated in an incorrect location and thus you are thinking it's not working. If you want a more concrete answer you'll have to comment on this answer with the specific problem you are facing (i.e. what specifically is "wrong"?).

how hibernate deal with like keyword in query sentence

Here met a hesitation about the way hibernate dealing with like keyword in query sentence.This's a small snippet in DaoImpl and see it first:
public List<T> findBySQL(String sql, String... params){
SQLQuery query = getSession().createSQLQuery(sql);
query.addEntity(clazz);
for (int i = 0; i < params.length; i++){
query.setParameter(i, params[i]);
}
List<T> list = query.list();
return list;
}
ok! without any doubt and use it in below controller:
#RequestMapping(value = "/getFirst/{var}", produces = "application/json; charset=utf-8")
public #ResponseBody Site getFirst(#PathVariable String var){
String fr = "select * from Food f where f.resname = ?";
List<Site> siteList = siteService.findBySQL(fr, var);
Site first = siteList.get(0);
return first;
}
here is the result:{"src":"http://p0.meituan.net/350.214/deal/ac8ba922d7a6030325976fb31e51b4ce38985.jpg","resname":"哈哈派"}
but when i change such sql sentence like this using like and without amending anything else:
String fr = "select * from Food f where f.resname like '%?%'";
List<Site> siteList = siteService.findBySQL(fr, var);
redeploy and run, exception appear:
HTTP Status 500 - Request processing failed; nested exception is org.hibernate.QueryParameterException: Position beyond number of declared ordinal parameters. Remember that ordinal parameters are 1-based! Position: 1
but i don't think it's the parameter index problem, maybe something error or maybe like can not be used like such way? so i wonder how hibernate deal with 'like' keyword?
You should add the wildchar(%) to the parameter and not the query. So modify your query as below.
String fr = "select * from Food f where f.resname like ? ";
List<Site> siteList = siteService.findBySQL(fr, "%"+var+"%");
OR
String fr = "select * from Food f where f.resname like ? ";
List<Site> siteList = siteService.findBySQL(fr, new String[]{"%"+var+"%"});

grails json converter only returns strings not numbers, integers or doubles

I have a database table that stores the structure of a simple table. The table contains user data. The user can define how the table is set up. Thus I store values and their types. Everything is a string in the stored table. I need to pass this as JSON to the browser client, which does some JavaScript on the JSON. But, I want numeric values and string values in the JSON object, but the Grails JSON converter, only spits out Strings
My Service has:
def testMap(){
//my results from a query
List query = [["name":"price","value":"4.23","type":"double"],["name":"title","value":"box","type":"string"]]
Map results = [:]
query.each{ row ->
if (row.type == "double"){
results << [(row.name): row.value]
}
else
{
//what do I do here?
results << [(row.name): row.value]
}
}
return results
}
My Controller has...
def showMap(){
render touchSourceSystemService.testMap() as JSON
}
The results are...
{"price":"4.23","title":"box"}
But I need the price to be numeric, not a string, like this.
{"price":4.23,"title":"box"}
I had this same issue. The only way I could get it to work was like this...
Add this to top of your Service Class:
import groovy.json.*
And in your Service method, do this:
def testMap(){
//my results from a query
List query = [[name:"price",value:"4.23",type:"double"],[name:"title",value:"box",type:"string"]]
def slrp = new JsonSlurper()
def results = [:]
query.each{ row ->
if (row.type == "double"){
//results << ["'${row.name}'": "${row.value}"]
results << slrp.parseText('{"' + row.name + '":' + row.value + '}')
}
else
{
//what do I do here?
results << slrp.parseText('{"' + row.name + '":"' + row.value + '"}')
//results << ["'${row.name}'": "'${row.value}'"]
}
}
return results
}
Your controller should now return this:
{"price":4.23,"title":"box"}