-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added a new SQL parser. This parser supports both SQL style line comm…
…ents and comment blocks. SQL statements can span multiple lines but must be delimited with a semicolon. This allows for improved readability of SQL scripts. The old parser expects one statement per line which may or may not end with a semicolon. This means the new parser can also process scripts written for the old parser if those scripts end each line with a semicolon. For backwards compatibility reasons this parser isn't used unless the manifest contains a meta-data entry "AA_SQL_PARSER" with the value "delimited". If this value isn't specified or is set to "legacy" the old parser implementation is used.
- Loading branch information
1 parent
bd98740
commit 55208f6
Showing
5 changed files
with
304 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
|
||
package com.activeandroid.util; | ||
|
||
import android.database.Cursor; | ||
|
||
import java.io.Closeable; | ||
import java.io.IOException; | ||
|
||
import com.activeandroid.util.Log; | ||
|
||
|
||
public class IOUtils { | ||
|
||
/** | ||
* Unconditionally close a {@link Closeable}. | ||
* <p/> | ||
* Equivalent to {@link Closeable#close()}, except any exceptions will be ignored. This is | ||
* typically used in finally blocks. | ||
* @param closeable A {@link Closeable} to close. | ||
*/ | ||
public static void closeQuietly(final Closeable closeable) { | ||
|
||
if (closeable == null) { | ||
return; | ||
} | ||
|
||
try { | ||
closeable.close(); | ||
} catch (final IOException e) { | ||
Log.e("Couldn't close closeable.", e); | ||
} | ||
} | ||
|
||
/** | ||
* Unconditionally close a {@link Cursor}. | ||
* <p/> | ||
* Equivalent to {@link Cursor#close()}, except any exceptions will be ignored. This is | ||
* typically used in finally blocks. | ||
* @param cursor A {@link Cursor} to close. | ||
*/ | ||
public static void closeQuietly(final Cursor cursor) { | ||
|
||
if (cursor == null) { | ||
return; | ||
} | ||
|
||
try { | ||
cursor.close(); | ||
} catch (final Exception e) { | ||
Log.e("Couldn't close cursor.", e); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
|
||
package com.activeandroid.util; | ||
|
||
import java.io.BufferedInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
|
||
public class SqlParser { | ||
|
||
public final static int STATE_NONE = 0; | ||
public final static int STATE_STRING = 1; | ||
public final static int STATE_COMMENT = 2; | ||
public final static int STATE_COMMENT_BLOCK = 3; | ||
|
||
public static List<String> parse(final InputStream stream) throws IOException { | ||
|
||
final BufferedInputStream buffer = new BufferedInputStream(stream); | ||
final List<String> commands = new ArrayList<String>(); | ||
final StringBuffer sb = new StringBuffer(); | ||
|
||
try { | ||
final Tokenizer tokenizer = new Tokenizer(buffer); | ||
int state = STATE_NONE; | ||
|
||
while (tokenizer.hasNext()) { | ||
final char c = (char) tokenizer.next(); | ||
|
||
if (state == STATE_COMMENT_BLOCK) { | ||
if (tokenizer.skip("*/")) { | ||
state = STATE_NONE; | ||
} | ||
continue; | ||
|
||
} else if (state == STATE_COMMENT) { | ||
if (isNewLine(c)) { | ||
state = STATE_NONE; | ||
} | ||
continue; | ||
|
||
} else if (state == STATE_NONE && tokenizer.skip("/*")) { | ||
state = STATE_COMMENT_BLOCK; | ||
continue; | ||
|
||
} else if (state == STATE_NONE && tokenizer.skip("--")) { | ||
state = STATE_COMMENT; | ||
continue; | ||
|
||
} else if (state == STATE_NONE && c == ';') { | ||
final String command = sb.toString(); | ||
commands.add(command); | ||
sb.setLength(0); | ||
continue; | ||
|
||
} else if (state == STATE_NONE && c == '\'') { | ||
state = STATE_STRING; | ||
|
||
} else if (state == STATE_STRING && c == '\'') { | ||
state = STATE_NONE; | ||
|
||
} | ||
|
||
if (state == STATE_NONE || state == STATE_STRING) { | ||
if (state == STATE_NONE && isWhitespace(c)) { | ||
if (sb.length() > 0 && sb.charAt(sb.length() - 1) != ' ') { | ||
sb.append(' '); | ||
} | ||
} else { | ||
sb.append(c); | ||
} | ||
} | ||
} | ||
|
||
} finally { | ||
IOUtils.closeQuietly(buffer); | ||
} | ||
|
||
if (sb.length() > 0) { | ||
commands.add(sb.toString()); | ||
} | ||
|
||
return commands; | ||
} | ||
|
||
private static boolean isNewLine(final char c) { | ||
return c == '\r' || c == '\n'; | ||
} | ||
|
||
private static boolean isWhitespace(final char c) { | ||
return c == '\r' || c == '\n' || c == '\t' || c == ' '; | ||
} | ||
} |
Oops, something went wrong.