I want to perform simple operations using one test model I created using Protégé 5. In my case I have a user defined this way in my owl file:
<owl:NamedIndividual rdf:about="&user-test-2;u01">
<rdf:type rdf:resource="&user-test-2;user"/>
<user-test-2:email rdf:datatype="&xsd;string">email1#test.net</user-test-2:email>
<user-test-2:hasGender rdf:resource="&user-test-2;male"/>
<user-test-2:isYearsOld rdf:resource="&user-test-2;18-24"/>
</owl:NamedIndividual>
I have been able to load the model correctly and perform a basic search using SPARQL to get male users and related properties, obtaining the following results:
String fileName = "user-test-2.owl";
Model model = RDFDataMgr.loadModel(fileName);
final String ns = "http://www.semanticweb.org/ontologies/user-test-2#";
String queryString = "PREFIX test: <http://www.semanticweb.org/ontologies/user-test-2#> "
+ "SELECT ?subject "
+ "WHERE { ?subject test:hasGender test:male } ";
QueryExecution qe = QueryExecutionFactory.create(query, model);
ResultSet results = qe.execSelect();
ResultSetFormatter.out(System.out, results, query);
------------
| subject |
============
| test:u01 |
-----------
Now I would like to access the properties of the owl:NamedIndividual and update one of them. For instance, to change the user's email.
EDIT
I have been able to access the properties using this code:
Property emailDp = model.getProperty(ns + "email");
Property isYearsOld = model.getProperty(ns + "isYearsOld");
for ( ; results.hasNext() ; ) {
QuerySolution soln = results.nextSolution() ;
Resource res = soln.getResource("subject");
Resource user = model.getResource( res.getURI());
System.out.println(user.getProperty(emailDp));
System.out.println(user.getProperty(isYearsOld));
}
Now I would need to update one of them.
For the moment I have not found any useful example to perform these kind of things so any help is welcome.
Thanks in advance.
So you want to update the property emailDp or isYearsOld of a given user.
Assuming a user only has one e-mail address and/or one age, we can get the property directly by calling:
Statement emailStatement = user.getProperty(emailDp);
Statement ageStatement = user.getProperty(isYearsOld);
The age or email of a user can then be retrieven using:
Resource email = (Resource) emailStatement.getObject();
Resource age = (Resource) ageStatement.getObject();
Updating either one of these can easily be done by:
user.removeProperty(emailDp, email);
user.removeProperty(isYearsOld, age);
user.addProperty(emailDp, newEmail);
user.addProperty(isYearsOld, newAge);
If a user has MORE THAN ONE of either, you will have to device if the new e-mail address replaces all old ones with user.removeAll(emailDp) or iterating over the list as you are doing and performing any kind of check, and delete the one you want, similar to above examples.
Related
I have created a function with Kotlin using azure-functions-kotlin-archetype. I have created a Http Trigger and a cosmos input binding to read data from the cosmos. I have mentioned sql query also to fetch the data. I want to pass path variable to the http trigger which should be used as parameter in the query.
As per Microsoft documentation I have defined the path parameter accordingly.
https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-cosmosdb-v2-input?tabs=java#http-trigger-get-multiple-docs-from-route-data-using-sqlquery-java
But I am getting blank response, means no data is fetched. If I hard code the parameter in the Sql query, I able to fetch the data. Can any one please tell me the issue here. The Function Code is as below
#FunctionName("GetData")
fun run(
#HttpTrigger(
name = "req",
methods = [HttpMethod.GET],
authLevel = AuthorizationLevel.ANONYMOUS,
route = "/api/getItems/{id}/{qnt}"
)
request: HttpRequestMessage<Optional<String>>,
#CosmosDBInput(
name = "cosmosdb",
databaseName = "item-db",
collectionName = "item",
sqlQuery = "SELECT * FROM ITEM n where n.id= {id} "
+"and n.qnt = {qnt}",
connectionStringSetting = "Cosmos_DB_Connection_String"
)
rs: Array<String>,
context: ExecutionContext): HttpResponseMessage {
return request
.createResponseBuilder(HttpStatus.OK)
.body(rs)
.build()
}
}
According to the sample query you provided: SELECT * FROM ITEM n where n.id= {'ID1'} " +"and n.qnt = {1}, it seems the id is string and qnt is a number. When we get the parameters from route, it will treat the parameters as string. So if you use the parameters from route in sqlQuery directly, it will select the data like this sql: SELECT * FROM ITEM n where n.id = 'ID1' and n.qnt = '1'. So no data is fetched.
You need to get the parameter qnt as a number but not as string from route, so please use route = "api/getItems/{id}/{qnt:int}".
===========================Update=========================
Add this update for other communities reference:
Use the method StringToNumber() in sql query like sqlQuery = "SELECT * FROM ITEM n where n.id= {id} " + "and n.qnt = StringToNumber({qnt})".
I have a web application that I am trying to "break".There's a login page that requires username and password input. Let's say I have a table Auser that stores username's info in MySQL.
When I hit Login after keying the credentials,it executes this line of code:
String sql = "select object(o) from Auser as o where ausername='" + username + "'";
Now, I know not using preparedStatement makes SQL query vulnerable to SQL injection and I want to perform such a stunt. I created a dummy table called test for the purpose of able to drop this table via the injection command.
I tried various ways like in my username input(root is the username):
root` DROP TABLE test;
And it didn't work. Is there a way to make my injection successful?
Update:
Just extra info, my username column is VARCHAR(255) and my method for getting the username is below:
public Auser get(String username, boolean moreInfo) {
try {
Auser u = null;
String sql = "select object(o) from Auser as o where ausername='" + username + "'";
List resList = em.createQuery(sql).getResultList();
if (resList == null) { // null check for sql query / library error
msg = CoreUtil.wrapMsg(CoreUtil.FUNC_ERROR,
this.getClass().getName(), "get[" + username + "]", "query error AUSER.");
} else if (resList.isEmpty()) {
msg = "User " + username + " not found.";
} else {
u = (Auser) resList.get(0);
}
return u;
} catch (Exception e) {
msg = CoreUtil.wrapMsg(CoreUtil.FUNC_ERROR,
this.getClass().getName(), "get[" + username + "]", e.getMessage());
return null;
}
}
Seems every solution, I tried keeps throwing IllegalArgumetnException and the table still remains.I just want to exploit the vulnerabilities of my program,it can be any kind of injection whether dropping a table, returning all users info,etc.
The EntityManager has some (very) basic protection built in that won't run more than one command in the same SQL statement.
This will protect you from Robert'); DROP TABLE Students; --, but it won't protect from attackers trying to expand/alter the one query that's being run.
For example, in your code an attacker could get the details of another user by entering the username ' OR 1 = 1 --; This would make the SQL string being executed
select object(o) from Auser as o where ausername='' OR 1 = 1 --'
which will select every user in the table (note that the -- at the end of the input will comment out everything after the injected code), and your method will return the first user in the result list This will potentially give the attacker details about another user that they should not have access to. If the first account is an administrator account then they may also have access they should not have.
An attacker can also learn the structure of the table this way - they can try strings like ' and IS_ADMIN = IS_ADMIN --, or ' OR ID = 0 --. If they try enough of these (and attacks like this can be easily automated) they will find valid column names when the query doesn't throw an error. They can potentially then make a more targeted injection attack to gain access to an admin account.
They might also learn things from the error message returned from a failed attempt, such as the DB platform, which can make attacks easier.
String sql = "select object(o) from Auser as o where ausername='" + username + "'";
If you want to delete the test table
username = "x'; DROP TABLE test AND '1'='1"
If you want to see all fields of all ausers entries
username = "x' OR '1'='1"
I'm trying to use EsperIO to load some information from database and use it in other queries with different conditions. To do it I'm using the following code:
ConfigurationDBRef dbConfig = new ConfigurationDBRef();
dbConfig.setDriverManagerConnection("org.postgresql.Driver",
"jdbc:postgresql://localhost:5432/myDatabase",
"myUser", "myPassword");
Configuration engineConfig = new Configuration();
engineConfig.addDatabaseReference("myDatabase", dbConfig);
// Custom class
engineConfig.addEventType("UserFromDB", UserDB.class);
EPServiceProvider esperEngine = EPServiceProviderManager.getDefaultProvider(engineConfig);
String statement = "insert into UserFromDB "
+ " select * from sql:myDatabase ['SELECT * from data.user']";
//Install this query in the engine
EPStatement queryEngineObject = esperEngine.getEPAdministrator().createEPL(statement);
// 1. At this point I can iterate over queryEngineObject without problems getting the information sent by database
// This query is only a 'dummy example', the 'final queries' are more complex
statement = "select * from UserFromDB";
EPStatement queryEngineObject2 = esperEngine.getEPAdministrator().createEPL(statement);
// 2. If I try to iterate over queryEngineObject2 I receive no data
How can I reuse UserFromDB stored information in other queries? (in the above example, in queryEngineObject2)
You don't have a stream since the database doesn't provide a stream. The database query provides rows only when its being iterated/pulled.
One option is to loop over each row and send it into the engine using "sendEvent":
// create other EPL statements before iterating
Iterator<EventBean> it = statement.iterator();
while(it.hasNext()) {
epService.getEPRuntime().sendEvent(event);
}
Not an SQL expert:
I am currently implementing a Searching Web Application. The user will send a GET request to a particular Endpoint.
The Endpoint will accept a set of URL Params and the request can come with optional fields. Such as 1, 2 or 3 fields.
My Database table for USER looks like this.
+--------------+---------+------+-----+---------+----------------+
| id | firstName | lastName | email | zip | phone |
+--------------+---------+------+-----+---------+----------------+
Now the web application will get a GET Request with either Phone or Zip or Email.
I have two solutions for doing this but both look bad:
Solution 1:
Have multiple SQL Queries and Execute them according to the URL Params, I receive.
Select * from User where phone=1111111111 and zip=12345 and email=test#email.com;
Select * from User where phone=1111111111 and zip=12345;
...
...
And so on........I will end up having many queries and this will be a bad implementation. Also will be bad to maintain.
Solution 2:
Other solution that I am thinking of is to have a method, which will build an SQL query based on the URL Params I receive.
Example:
buildSQLQuery(phone,zip,email){
String sql = "Select * from User where "
if(phone!=null && email!=null && zip!=null ){
sql = sql + "phone = " + phone + " and zip = " + zip + " and email = " + email;
}else if (phone!=null && email!=null && zip==null){
sql = sql + "phone = " + phone + " and email = " + email;
}
.......
......
And so on have all conditions and build that particular query.
}
I don't like both these solutions.
Is there a way to write a Single SQL query and that will handle all the above conditions.
Something like if the URL Param value is NULL then that should not affect the query and I will get my expected results.
As in my case the optional values, which don't come in are set to NULL.
Can I implement something like this?
Select * from User where (if notNull (phone))(phone = phone ) and (if notNull (email))(email = email ) and (if notNull (zip))(zip = zip )
If any of the above one value is null then don't use that part in where Condition.
Also I will always have one field present, so there will be no case where all values are null.
I am implementing this web application in Java and Spring MVC. If anyone can guide me in the correct direction.
Thank you.
I think one more possible solution like:
String sql = "Select * from User where 1=1 "
if(phone!=null){
sql += " and phone = " + phone ;}
if(email!=null){
sql += " and email = " + email ;}
if(zip!=null){
sql += " and zip = " + zip ;}
OR You can try following single query:
select * from User
where (#phone is null OR phone = #phone) AND (#email is null OR email = #email) AND (#zip is null OR zip = #zip)
You can do like this:
SELECT * FROM User where(
IF($phone != 0, IF(phone = $phone,1,0), 0) AND
IF($email != 0, IF(email = $email,1,0),0) AND
IF($zip != 0, IF(zip = $zip,1,0),0)
)
assumed for PHP you can change the syntax, may be this query not do the job completely but if you provide fiddle i will modify this to give the proper result.
I have a form where user can select search criteria.
The criterias are say:
Product Name: Input field
Name Option: Radio button group - begins with (default selected)/ is/ contains
Country: dropdown of country
Status: All, Active, Blocked
Type: All, One, Two, Three
Only Product Name is mandatory. Other dropdowns are optional.
So if country is not given, I should find products for all countries.
If active is not given, I should find both active and blocked products.
If Type is not given, I should return all the three types products.
I am building hibernate query as below:
String productName = searchCriteria.getValue("productName");
String productNameCriteria = searchCriteria.getValue("productNameCriteria");
String country = searchCriteria.getValue("country");
String status = searchCriteria.getValue("status");
String type = searchCriteria.getValue("type");
Query prodQuery = null;
String prodSql = "select count(*) from Product p where";
// is
if (productNameCriteria.equalsIgnoreCase("IS")){
prodSql += "p.productName = '"+productName+"'";
}
// begins with
else if (productNameCriteria.equalsIgnoreCase("BEGINS WITH")){
prodSql += "p.productName = '"+productName+"%'";
}
// contains
else (productNameCriteria.equalsIgnoreCase("BEGINS WITH")){
prodSql += "p.productName = '%"+productName+"%'";
}
if(!country.equalsIgnoreCase("0")){
prodSql += " and p.country = '"+country+"'";
}
if(!status.equalsIgnoreCase("ALL")){
if(status.equalsIgnoreCase("active"))
prodSql += " and p.status = 'active'";
else
prodSql += " and p.status = 'blocked'";
}
if(!type.equalsIgnoreCase("ALL")){
if(type.equalsIgnoreCase("one"))
prodSql += " and p.type = 'one'";
else if(type.equalsIgnoreCase("two"))
prodSql += " and p.type = 'two'";
else
prodSql += " and p.type = 'three'";
}
prodQuery = this.em.createQuery(prodSql);
List<Object[]> results = prodQuery.getResultList();
Am I doing query building the right way ? Or is there any other efficient method ???
Thanks for reading!!
Try looking at Criteria Query
Criteria crit = sess.createCriteria(Product.class);
if (productNameCriteria.equalsIgnoreCase("IS"))
crit.add( Restrictions.eq("productName", productName);
else if (productNameCriteria.equalsIgnoreCase("BEGINS WITH"))
crit.add( Restrictions.like("productName", productName + "%")
// etc
If you absolutely must build a string query then you should be using a StringBuilder
StringBuilder sb = new StringBuilder();
sb.append("select count(*) from Product p where ");
if (productNameCriteria.equalsIgnoreCase("IS"))
sb.append("p.productName = '").append(productName).append("'");
// etc
String query = sb.toString();
Using a StringBuilder reduces the number of instances created at runtime.
You could also look into using query parameters, which would reduce some of the query complexity, though I don't know what the runtime query performance effects are.
"select count(*) from Product p where p.productName = :productName"
"select count(*) from Product p where p.productName = ?"
You can then use Query#setParameter (or one of the other variants like setString) to define the values in the query. This is also a much, much better way of building the query because it's going to automatically manage quoting and escaping of values you're receiving from the UI. Use query parameters and not string concatenation, regardless of how you build the query string.
Yes .It will work if you build the query dynamically in this way .But the code will become tedious and noisy as it involves string manipulating of the where-condition clause .
For this kind of query 's use case , which is a search that allows users to specify a range of different property values to be matched by the returned result set , using Query By Example(QBE) is more efficient and elegant.
The idea of QBE is that you provide an instance of the queried class with some properties initialized, and the query will returns the records with matching property values.
Reference
Example JavaDocs
YouTube Hibernate Tutorial - Projections and Query By Example