public static List<FieldOption>
getFieldOptionListOfField(PersistenceManager pm, long fieldId) throws NoSuchFieldOptionException {
Query query = pm.newQuery(FieldOption.class);
try {
query.setFilter("this.fieldId == fieldId");
query.declareParameters("long fieldId");
query.setOrdering("orderId ascending");
List<FieldOption> fieldOptions = (List<FieldOption>) query.execute(fieldId);
logger.debug("fieldOptions = " + fieldOptions);
return fieldOptions();
} finally {
query.closeAll();
}
}
After execution of excute method 'fieldOptions' is having certain values. But after closeAll() the list becomes empty. Can you please suggest why it happens?
The "List" returned after you end a transaction and close a PM is not a real List, but instead a lazy load list, that cannot lazy load once it has no connection to the datastore. Easiest option is put (copy) the query results into your own List before closing the txn/PM.
Related
public Connection executeUpdate() {
long start = System.currentTimeMillis();
try {
this.logExecution();
PreparedStatement statement = this.buildPreparedStatement();
this.connection.setResult(statement.executeUpdate());
this.connection.setKeys(this.returnGeneratedKeys ? statement.getGeneratedKeys() : null);
this.connection.setCanGetKeys(this.returnGeneratedKeys);
} catch (SQLException var7) {
this.connection.onException();
throw new Sql2oException("Error in executeUpdate, " + var7.getMessage(), var7);
} finally {
this.closeConnectionIfNecessary();
}
long end = System.currentTimeMillis();
logger.debug("total: {} ms; executed update [{}]", new Object[]{end - start, this.getName() == null ? "No name" : this.getName()});
return this.connection;
}
I'm wondering how to test an update failing. The query I'm using is:
update my_table set some_field=:some_value
where the_key = :the_key_value
And, immediately before executeUpdate() runs, I am deleting the record where the_key == "the_key_value".
Does anyone know the correct way to determine if the update failed?
Also, when I go to the javadoc and click on anything, I get:
CDN object Not Found - Request ID: c6a9ba5f-f8ea-46ae-bf7a-efc084971878-19055563
Is there a way to build javadoc locally?
EDIT: is the way to check this thru the use of Connection.getResult()? Does it return the number of records updated/inserted etc?
I went and RTFM which explained how to do this.
I want to return a List of "Posts" from an endpoint with optional pagination.
I need 100 results per query.
The Code i have written is as follows, it doesn't seem to work.
I am referring to an example at Objectify Wiki
Another option i know of is using query.offset(100);
But i read somewhere that this just loads the entire table and then ignores the first 100 entries which is not optimal.
I guess this must be a common use case and an optimal solution will be available.
public CollectionResponse<Post> getPosts(#Nullable #Named("cursor") String cursor,User auth) throws OAuthRequestException {
if (auth!=null){
Query<Post> query = ofy().load().type(Post.class).filter("isReviewed", true).order("-timeStamp").limit(100);
if (cursor!=null){
query.startAt(Cursor.fromWebSafeString(cursor));
log.info("Cursor received :" + Cursor.fromWebSafeString(cursor));
} else {
log.info("Cursor received : null");
}
QueryResultIterator<Post> iterator = query.iterator();
for (int i = 1 ; i <=100 ; i++){
if (iterator.hasNext()) iterator.next();
else break;
}
log.info("Cursor generated :" + iterator.getCursor());
return CollectionResponse.<Post>builder().setItems(query.list()).setNextPageToken(iterator.getCursor().toWebSafeString()).build();
} else throw new OAuthRequestException("Login please.");
}
This is a code using Offsets which seems to work fine.
#ApiMethod(
name = "getPosts",
httpMethod = ApiMethod.HttpMethod.GET
)
public CollectionResponse<Post> getPosts(#Nullable #Named("offset") Integer offset,User auth) throws OAuthRequestException {
if (auth!=null){
if (offset==null) offset = 0;
Query<Post> query = ofy().load().type(Post.class).filter("isReviewed", true).order("-timeStamp").offset(offset).limit(LIMIT);
log.info("Offset received :" + offset);
log.info("Offset generated :" + (LIMIT+offset));
return CollectionResponse.<Post>builder().setItems(query.list()).setNextPageToken(String.valueOf(LIMIT + offset)).build();
} else throw new OAuthRequestException("Login please.");
}
Be sure to assign the query:
query = query.startAt(cursor);
Objectify's API uses a functional style. startAt() does not mutate the object.
Try the following:
Remove your for loop -- not sure why it is there. But just iterate through your list and build out the list of items that you want to send back. You should stick to the iterator and not force it for 100 items in a loop.
Next, once you have iterated through it, use the iterator.getStartCursor() as the value of the cursor.
I use the Wordpress function $wpdb->get_results()
https://codex.wordpress.org/Class_Reference/wpdb#SELECT_Generic_Results
It says:
"If no matching rows are found, or if there is a database error, the return value will be an empty array."
Then how can I know if the query failed OR if it's empty?
Use
$results=$wpdb->get_results($yoursql);
if (count($results)> 0){
//do here
}
But if you want to know if query failed
$wpdb -> show_errors ();
$wpdb -> get_results ($wpdb -> prepare($sql));
$wpdb -> print_error ();
Bit late to the party here but I'm just looking for the same thing. I've had a browse through the wp-db.php code on version 4.4.2.
On line 1422, inside the method flush() there's a bit of code which resets the last_error property:
$this->last_error = '';
This flush() method is called in the query() method on line 1693:
$this->flush();
The get_results() method calls query() on line 2322:
if ( $query ) {
$this->query( $query );
} else {
return null;
}
With this we can be pretty sure that more or less every time get_results() (Or get_row() too for that matter) is called, query() and flush() are both called, which ensures that last_error is set to the empty string before the query is executed.
So assuming the query runs (If it doesn't, null is returned - if the query is empty for example), last_error should contain an error message if the query was to fail for some reason.
Since last_error is flush()ed/reset each time, it should only contain an error for the last query that was run, rather than the last error for any query that had been run previously. With this in mind it should be safe to rely on last_error to determine whether something went wrong with the query.
$results = $wpdb->get_results($sql);
if (is_null($results) || !empty($wpdb->last_error)) {
// Query was empty or a database error occurred
} else {
// Query succeeded. $results could be an empty array here
}
Not the most intuitive in my opinion, but it seems to be sufficient.
Personally, I've written my own class around wpdb for my own benefit. This is my getResults() method.
public function getResults($query, $bindings = [])
{
// Prepare the statement (My prepare method inspects $query and just returns it if there's no bindings, otherwise it uses $wpdb->prepare()
$prepared = $this->prepare($query, $bindings);
// Execute the statement
$rows = $this->db->get_results($prepared, ARRAY_A);
// If an array was returned and no errors occurred, return the result set
if (is_array($rows) && empty($this->db->last_error)) {
return $rows;
}
// On failure, return false
return false;
}
Hope this helps.
Wpdb->get_results function from wordpress returns the result if successful otherwise it will return null. There can be many reasons if a query get failed.Refer in-depth article on debugging get_results() returning empty results here
Although you can use functions like wpdb->show_error() to check what was the last error after executing the sql query. sometimes this error returns empty
then try to use wpdb->last_query to check the final query that get formed.
I am trying to use a cursor with Objectify and Google App Engine to return a subset of data and a cursor so that I can retrieve more data when the user is ready. I found an example here that looks exactly like what I need but I don't know how to return the final list plus the cursor. Here is the code I have:
#ApiMethod(name = "listIconThemeCursor") //https://code.google.com/p/objectify-appengine/wiki/Queries#Cursors
public CollectionResponse<IconTheme> listIconThemeCursor(#Named("cursor") String cursorStr) {
Query<IconTheme> query = ofy().load().type(IconTheme.class).limit(10);
if (cursorStr != null ) {
query.startAt(Cursor.fromWebSafeString(cursorStr));
}
List<IconTheme> result = new ArrayList<IconTheme>();
int count = 0;
QueryResultIterator<IconTheme> iterator = query.iterator();
while (iterator.hasNext()) {
IconTheme theme = iterator.next();
result.add(theme);
count++;
}
Cursor cursor = iterator.getCursor();
String encodeCursor = cursor.toWebSafeString();
return serial(tClass, result, encodeCursor);
}
Note that this was modified from a previous endpoint in which I returned the CollectionResponse of ALL the data. My dataset is large enough that this is no longer practical. Basically, I don't know what was in the user's function of 'serial(tClass, result, encodeCursor) that let it get returned to the user.
There is another example here but it doesn't appear to answer my question either.
I don't quite understand what you are asking, but I see one immediate bug in your code:
query.startAt(Cursor.fromWebSafeString(cursorStr));
...should be:
query = query.startAt(Cursor.fromWebSafeString(cursorStr));
Objectify command objects are immutable, functional objects.
After a long slog, I figured out that CollectionResponse has the cursor in it :(
Here is the complete code I used incorporating the comment from stickfigure above:
#ApiMethod(name = "listIconThemeCursor", path="get_cursor")
public CollectionResponse<IconTheme> listIconThemeCursor(#Named("cursor") String cursorStr) {
Query<IconTheme> query = ofy().load().type(IconTheme.class)
.filter("errors <", 10)
.limit(10);
if (cursorStr != null ) {
query = query.startAt(Cursor.fromWebSafeString(cursorStr));
}
List<IconTheme> result = new ArrayList<IconTheme>();
QueryResultIterator<IconTheme> iterator = query.iterator();
while (iterator.hasNext()) {
IconTheme theme = iterator.next();
result.add(theme);
}
Cursor cursor = iterator.getCursor();
CollectionResponse<IconTheme> response = CollectionResponse.<IconTheme> builder()
.setItems(result)
.setNextPageToken(cursor.toWebSafeString())
.build();
return response;
}
Background
I have a list of sObjects I need to insert, but I must first check if the insert will be successful. So, I'm setting a database save point before performing the insert and checking the save results (for the insert statement). Because, I don't want to process if any errors occurred, if there were any errors in the insert results, the database is rolled back to the save point.
Problem & Question
I need to collect the errors for each save (insert) result and associate each error to the specific sObject record that caused the error. According to the documentation Save results contain a list of errors, the Salesforce ID of the record inserted (if successful), and a success indicator (boolean).
How do I associate the Save Result to the original sObject record inserted?
Code/Example
Here's an example I put together that demonstrates the concept. The example is flawed, in that the InsertResults don't always match the sObjectsToInsert. It's not exactly the code I'm using in my custom class, but it uses the same logic.
Map<Id,sObject> sObjectsToInsert; // this variable is set previously in the code
List<Database.SaveResult> InsertResults;
Map<String,sObject> ErrorMessages = new Map<String,sObject>();
System.SavePoint sp = Database.setSavepoint();
// 2nd parameter must be false to get all errors, if there are errors
// (allow partial successes)
InsertResults = Database.insert(sObjectsToInsert.values(), false);
for(Integer i=0; i < InsertResults.size(); i++)
{
// This method does not guarantee the save result (ir) matches the sObject
// I need to make sure the insert result matches
Database.SaveResult ir = InsertResults[i];
sObject s = sObjectsToInsert.values()[i];
String em = null; // error message
Integer e = 0; // errors
if(!ir.isSuccess())
{
system.debug('Not Successful');
e++;
for(Database.Error dbe : ir.getErrors()) { em += dbe.getMessage()+' '; }
ErrorMessages.put(em, s);
}
}
if(e > 0)
{
database.rollback(sp);
// log all errors in the ErrorMessages Map
}
Your comment says the SaveResult list is not guaranteed to be in order, but I believe that it is. I've used this technique for years and have never had an issue.