patternjavaMinor
BananaQuery - Android one-line query
Viewed 0 times
lineandroidqueryonebananaquery
Problem
I created this library just for fun. Since I was a bit tired to write 10 lines of code to execute a simple select query in Android, I created a way make it simple.
It's not so advanced and some Android query features are not ported, such as
About
Things I care about:
I removed all the documentation to let it fit here, that's why it's without documentation.
```
public class BananaQuery {
/ package / BananaQuery() {
}
public static BananaInsert insert(SQLiteDatabase database) {
return new BananaInsert(checkNotNull(database));
}
public static BananaSelect select(SQLiteDatabase database) {
return new BananaSelect(checkNotNull(database));
}
public static BananaUpdate update(SQLiteDatabase database) {
return new BananaUpdate(checkNotNull(database));
}
/ package / static T checkNotNull(T element) {
if (element == null) throw new NullPointerException("Null not valid here");
return element;
}
/ package / static Pair> parseNamedArguments(String condition, Map bindParams) {
List argumentsPair = new LinkedList();
Pattern pattern = Pattern.compile(":(\\w+)");
Matcher matcher = pattern.matcher(condition);
while (matcher.find()) {
String identifier = matcher.group(1);
if (!bindParams.containsKey(identifier)) {
It's not so advanced and some Android query features are not ported, such as
beginTransaction.BananaQuery is the main class which should be used to create instances of BananaUpdate, BananaInsert and BananaSelect.About
checkNotNull: I know Guava has it, but I don't want to include a library for one method.Things I care about:
- Everything
- I would like to avoid to repeat some blocks of code, see
valuemethods They are the same in the 3 classes! too forexecutemethod. Ah, and for the algorithm methods too.
- Named arguments: I created a way to allow to use named arguments (
:nameinstead of?), but I would like to improve it since it executes two times the same Regex.
I removed all the documentation to let it fit here, that's why it's without documentation.
BananaQuery```
public class BananaQuery {
/ package / BananaQuery() {
}
public static BananaInsert insert(SQLiteDatabase database) {
return new BananaInsert(checkNotNull(database));
}
public static BananaSelect select(SQLiteDatabase database) {
return new BananaSelect(checkNotNull(database));
}
public static BananaUpdate update(SQLiteDatabase database) {
return new BananaUpdate(checkNotNull(database));
}
/ package / static T checkNotNull(T element) {
if (element == null) throw new NullPointerException("Null not valid here");
return element;
}
/ package / static Pair> parseNamedArguments(String condition, Map bindParams) {
List argumentsPair = new LinkedList();
Pattern pattern = Pattern.compile(":(\\w+)");
Matcher matcher = pattern.matcher(condition);
while (matcher.find()) {
String identifier = matcher.group(1);
if (!bindParams.containsKey(identifier)) {
Solution
Pattern Matching
Let's focus on just this one method, for a moment:
First, the slow part of this method is probably compiling the pattern, and you do it multiple times, each time the method is called.
First, you compile it explicitly, second, you do a
How can this be improved?
Well, Patterns are thread-safe, and reusable. Let's move the pattern compile to be a static, final field:
Now there is no need to ever compile that again.
The second time the pattern is used, it is used to replace the parameter named placeholders with the
Let's focus on just this one method, for a moment:
static Pair> parseNamedArguments(String condition, Map bindParams) {
List argumentsPair = new LinkedList();
Pattern pattern = Pattern.compile(":(\\w+)");
Matcher matcher = pattern.matcher(condition);
while (matcher.find()) {
String identifier = matcher.group(1);
if (!bindParams.containsKey(identifier)) {
throw new IllegalStateException("Named argument " + identifier + " is not binded.");
}
argumentsPair.add(bindParams.get(identifier).toString());
}
condition = condition.replaceAll(":(\\w+)", "?");
return Pair.create(condition, argumentsPair);
}First, the slow part of this method is probably compiling the pattern, and you do it multiple times, each time the method is called.
First, you compile it explicitly, second, you do a
replaceAll later on with the same pattern.How can this be improved?
Well, Patterns are thread-safe, and reusable. Let's move the pattern compile to be a static, final field:
private static final Pattern COLONWORD = Pattern.compile(":(\\w+)");Now there is no need to ever compile that again.
The second time the pattern is used, it is used to replace the parameter named placeholders with the
? placeholder. How can this be improved? By doing the replacements during the initial matcher loop. Consider the following code:private static final Pattern COLONWORD = Pattern.compile(":(\\w+)");
static Pair> parseNamedArguments(String condition, Map bindParams) {
List argumentsPair = new LinkedList();
Matcher matcher = COLONWORD.matcher(condition);
StringBuffer buffer = new StringBuffer(condition.length());
while (matcher.find()) {
String identifier = matcher.group(1);
if (!bindParams.containsKey(identifier)) {
throw new IllegalStateException("Named argument " + identifier + " is not binded.");
}
argumentsPair.add(bindParams.get(identifier).toString());
matcher.appendReplacement(buffer, "?");
}
matcher.appendTail(buffer);
return Pair.create(buffer.toString(), argumentsPair);
}Code Snippets
static Pair<String, List<String>> parseNamedArguments(String condition, Map<String, Object> bindParams) {
List<String> argumentsPair = new LinkedList<String>();
Pattern pattern = Pattern.compile(":(\\w+)");
Matcher matcher = pattern.matcher(condition);
while (matcher.find()) {
String identifier = matcher.group(1);
if (!bindParams.containsKey(identifier)) {
throw new IllegalStateException("Named argument " + identifier + " is not binded.");
}
argumentsPair.add(bindParams.get(identifier).toString());
}
condition = condition.replaceAll(":(\\w+)", "?");
return Pair.create(condition, argumentsPair);
}private static final Pattern COLONWORD = Pattern.compile(":(\\w+)");private static final Pattern COLONWORD = Pattern.compile(":(\\w+)");
static Pair<String, List<String>> parseNamedArguments(String condition, Map<String, Object> bindParams) {
List<String> argumentsPair = new LinkedList<String>();
Matcher matcher = COLONWORD.matcher(condition);
StringBuffer buffer = new StringBuffer(condition.length());
while (matcher.find()) {
String identifier = matcher.group(1);
if (!bindParams.containsKey(identifier)) {
throw new IllegalStateException("Named argument " + identifier + " is not binded.");
}
argumentsPair.add(bindParams.get(identifier).toString());
matcher.appendReplacement(buffer, "?");
}
matcher.appendTail(buffer);
return Pair.create(buffer.toString(), argumentsPair);
}Context
StackExchange Code Review Q#56135, answer score: 4
Revisions (0)
No revisions yet.