Singleton designs are never as efficient as static variables, which are not as efficient as local (method) variables. Do feel free to use static variables to cache common queries, but do not use them to cache unmetered results, such as describe calls. Depending on the object being described, it can actually increase the CPU time used.
As an example, I give you this:
public class AccountSObjectType {
static DescribeSObjectResult instance;
public static DescribeSObjectResult getDescribe() {
if(instance == null) instance = Account.SObjectType.getDescribe();
return instance;
}
}
In my org, I ran this for a baseline:
Long start = DateTime.now().getTime();
for(Integer i = 0; i < 100000; i++) {
DescribeSObjectResult recordTypeId = Account.SObjectType.getDescribe();
}
Long stop = DateTime.now().getTime();
System.assert(false, stop-start);
The result was about 1900 milliseconds. I figured that using the singleton should improve my performance, right?
Long start = DateTime.now().getTime();
for(Integer i = 0; i < 100000; i++) {
DescribeSObjectResult recordTypeId = AccountSObjectType.getDescribe();
}
Long stop = DateTime.now().getTime();
System.assert(false, stop-start);
The first run result of that was about 3800 ms (subsequent runs got no lower than about 2400 ms). That's right. 50-100% more CPU time than the direct call. The Singleton actually failed to outperform a describe called directly from a Schema object.
So, use the Singleton as a convenience tool (e.g. gather data all in one place), but do not always expect it to give you a boost in performance.
Returning null
from your save
method will leave you on the same page.
The Document
instance that the file upload will populate is the standard controller one:
public class documentExt {
private ApexPages.StandardController sc;
public documentExt(ApexPages.StandardController sc) {
this.sc = sc;
}
public PageReference save() {
Document d = (Document) sc.getRecord();
System.debug('document name ' + d.name);
// "My Personal Documents" folder
d.FolderId = UserInfo.getUserId();
insert d;
return null;
}
}
The error querying the Folder
objects suggests that a folder of the name you specify doesn't exist. To detect that, assign the query results to a list so you can check its size:
Folder[] folders = [select id from Folder where name='Financial' LIMIT 1];
if (folders.size() == 0) {
// Insert folder
}
Best Answer
Here's a solution using javascript. I'm also using jquery but you could modify it to select the apex:inputfile by its full ID and use vanilla javascript. It's using 500k as an arbitrary limit, but you can set it to whatever you want. The 'attachmentID' is the ID set on the apex:inputfile :