benestar / asparagus Goto Github PK
View Code? Open in Web Editor NEWSPARQL abstraction layer for PHP
License: GNU General Public License v2.0
SPARQL abstraction layer for PHP
License: GNU General Public License v2.0
In QueryConditionBuilder
we want to support filter, filterExists, filterNotExists, optional, union, minus and maybe even more operations.
When distributing derived works, the source code of the work must be made available under the same license.
The GNU General Public License v2.0 do not let companies use your project without applying the same license to its whole product. And it can be a pain to apply on a large company work.
Please considere using MIT License as a second license or replace with this one.
It will add a space in the operator so <= will become < =
Our QueryBuilder currently provides:
Furthermore, we have services to send queries to SPARQL endpoints and to format a query to make it human-readable.
To make sure that this library is actually useful and doesn't miss importing features as well as to find bugs not discovered by the unit tests, more integration tests are needed.
For example, all queries from https://www.mediawiki.org/wiki/Wikibase/Indexing/SPARQL_Query_Examples should be supported.
Apache Jena allows lucene queries like:
SELECT DISTINCT ?subject
WHERE {
?subject text:query (skos:prefLabel 'a*' 10);
}
When I try to create this query:
$q = new QueryBuilder($prefixes);
$q->select('?subject')
->where('?subject', "text:query (skos:prefLabel '$term' 10)");
It throws an exception:
Message: $expression has to be a variable or a path, got text:query (skos:prefLabel 'a*' 10)
Is there currently a way to use text:query and if not can we add it to the validator or as expression?
A way is needed to support adding user input safely to a SPARQL query. This could either mean something like a setParameter
method like done by dbal or some stricter syntax checks overall.
I have the following query:
$query = $q->selectDistinct('?label')
->where('?subject', 'skos:prefLabel', '?label')
->union(
$q->newSubgraph()->where('?subject', 'skos:prefLabel', '?label'),
$q->newSubgraph()->where('?subject', 'skos:altLabel', '?label')
)
->filter('regex(str(?label), ' . $eTerm . ', "i")');
Now i would expect the filter to be added after the union:
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
SELECT DISTINCT ?label WHERE {
{
?subject skos:prefLabel ?label .
}
UNION {
?subject skos:altLabel ?label .
}
FILTER (regex(str(?label), "radi")) .
}
LIMIT 20 OFFSET 0
But what it seems currently it is always added after the select what i get is:
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
SELECT DISTINCT ?label WHERE {
?subject skos:prefLabel ?label .
FILTER (regex (str (?label), "^radi", "i")) {
?subject skos:prefLabel ?label .
} UNION {
?subject skos:altLabel ?label .
}
}
It would be nice if the api allowed an easy way to add a filter on a optional clause.
perhaps a fourth parameter with filter could be added?
So a query like https://jena.apache.org/tutorials/sparql_optionals.html#optionals-with-filters could be created.
Create tests for all classes that currently exist to reach a high coverage and find issues more easily.
It would be nice if there was support for delete statements in the query builder which could handle delete and delete insert.
http://www.w3.org/TR/2013/REC-sparql11-update-20130321/#deleteData
http://www.w3.org/TR/2013/REC-sparql11-update-20130321/#deleteInsert
SELECT (COUNT(*) AS ?x)
is a variable definition and not a usage. There has to be a nicer way to find those variables and register them instead of just ignoring.
It would be nice if there was describe support, am currently looking what would be the best place to put it.
perhaps we can add a type var in the query builder when call ->describe() instead of ->select()
which determines what it returns on a ->format()
A common issue is to have a typo in variable names so that they don't appear in the result. To prevent such mistakes, we should validate that all variables defined in select
also actually appear in our query. The same applies to orderBy
/groupBy
and filter
.
This tasks doesn't include that all variables used in where
clauses etc. also have to be selected as there might be some auxiliary variables.
It would be nice if one could call optional
or filterExists
without creating a subgraph manually if only one condition should be added. Also, the next filter
or also
call should add information to the automatically created subgraph. This requries some context-awareness of GraphBuilder
and/or QueryBuilder
.
Avoid injection
ExpressionValidator
is a validator and should not do any tracking of variable or prefix usage. However, we should reuse the regexes from there somehow.
We need a more complex usage example in README.md to show how filters, optionals and unions work.
In SPARQL 1.1, predicates can also be paths like foo:bar/foo:baz
or a:b*
. These should be supported as well by the ExpressionValidator
.
newSubgraph() function returns GraphBuilder, not QueryBuilder. This makes it much harder to build an interface that can combine several parts via unions, since if there is one clause, it has to work with QueryBuilder (even worse, it's not even possible to get $graphBuilder out of QueryBuilder) but if there are several clauses, one has to work with GraphBuilder now, which despite having many of the same functions, does not share interface with QueryBuilder, so one has to have different functions for working with these cases. This is very inconvenient and prevents writing generic generators for queries.
Could be I did something wrong but my code is like:
$queryBuilder = new QueryBuilder( $prefixes );
$queryBuilder->select( '?place' )
->where( '?place', 'wdt:P131', 'wd:Q205690' );
$queryExecuter = new QueryExecuter( $url );
$result = $queryExecuter->execute( $queryBuilder->getSPARQL() );
Results are like:
{
"head" : {
"vars" : [ "place" ]
},
"results" : {
"bindings" : [ {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q8691"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q477733"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q570560"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q631448"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q678138"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q763293"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q800907"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q801459"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q801602"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q1197072"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q1278097"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q1287877"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q1592614"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q1718915"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q1757126"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q1966303"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q2000556"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q2090609"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q2379971"
}
}, {
"place" : {
"type" : "uri",
"value" : "http://www.wikidata.org/entity/Q6552450"
}
} ]
}
}'
so should the array key used to return the results be 'results' instead of 'search', or when/where does 'search' come from?
Currently we only check that variables and other parameters passed match the basic datatype. We should provide better validation based on regexes to check if the given variable name or IRI has the right format.
Lots of unit tests are missing for new classes and features introduced in Asparagus 0.3.
I think currently there is no bind support yet, I suppose this could be implemented the same way as the filter?
So you could do something like below:
$qb->bind('IF (BOUND (?var), ?bar, '') as ?bVar');
QueryBuilder::select
and QueryBuilder::groupBy
currently require functions to be wrapped by brackets. It would be nice if that could be done automatically.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.