Title: [767] trunk/activerecord-jdbc:
Improve performance of adapters by implementing recognizers in Java,
instead of doing a really bad-performing regexp
- Revision
- 767
- Author
- olabini
- Date
- 2007-10-16 07:34:34 -0400 (Tue, 16 Oct 2007)
Log Message
Improve performance of adapters by implementing recognizers in Java, instead of doing a really bad-performing regexp
Modified Paths
Diff
Modified: trunk/activerecord-jdbc/lib/active_record/connection_adapters/jdbc_adapter.rb (766 => 767)
--- trunk/activerecord-jdbc/lib/active_record/connection_adapters/jdbc_adapter.rb 2007-10-16 08:02:27 UTC (rev 766)
+++ trunk/activerecord-jdbc/lib/active_record/connection_adapters/jdbc_adapter.rb 2007-10-16 11:34:34 UTC (rev 767)
@@ -352,6 +352,14 @@
metadata.close rescue nil
end
+# def self.insert?(sql)
+# /\A\s*insert/i =~ sql
+# end
+
+# def self.select?(sql)
+# /\A\s*\(?\s*(select|show)/i =~ sql
+# end
+
private
def configure_jndi
jndi = @config[:jndi].to_s
@@ -483,16 +491,16 @@
_execute(sql,name)
end
end
-
+
+
# we need to do it this way, to allow Rails stupid tests to always work
# even if we define a new execute method. Instead of mixing in a new
# execute, an _execute should be mixed in.
def _execute(sql, name = nil)
- case sql.strip
- when /\Ainsert/i:
- @connection.execute_insert(sql)
- when /\A\(?\s*(select|show)/i:
- @connection.execute_query(sql)
+ if JdbcConnection::select?(sql)
+ @connection.execute_query(sql)
+ elsif JdbcConnection::insert?(sql)
+ @connection.execute_insert(sql)
else
@connection.execute_update(sql)
end
Modified: trunk/activerecord-jdbc/src/java/JdbcAdapterInternalService.java (766 => 767)
--- trunk/activerecord-jdbc/src/java/JdbcAdapterInternalService.java 2007-10-16 08:02:27 UTC (rev 766)
+++ trunk/activerecord-jdbc/src/java/JdbcAdapterInternalService.java 2007-10-16 11:34:34 UTC (rev 767)
@@ -101,6 +101,9 @@
cJdbcConn.defineFastMethod("write_large_object",cf.getFastOptSingletonMethod("write_large_object"));
+ cJdbcConn.getMetaClass().defineFastMethod("insert?",cf.getFastSingletonMethod("insert_p", IRubyObject.class));
+ cJdbcConn.getMetaClass().defineFastMethod("select?",cf.getFastSingletonMethod("select_p", IRubyObject.class));
+
RubyModule jdbcSpec = runtime.getOrCreateModule("JdbcSpec");
JDBCMySQLSpec.load(runtime, jdbcSpec);
JDBCDerbySpec.load(runtime, jdbcSpec);
@@ -108,6 +111,115 @@
return true;
}
+ private static int whitespace(int p, final int pend, ByteList bl) {
+ while(p < pend) {
+ switch(bl.bytes[p]) {
+ case ' ':
+ case '\n':
+ case '\r':
+ case '\t':
+ p++;
+ break;
+ default:
+ return p;
+ }
+ }
+ return p;
+ }
+
+ public static IRubyObject insert_p(IRubyObject recv, IRubyObject _sql) {
+ ByteList bl = _sql.convertToString().getByteList();
+
+ int p = bl.begin;
+ int pend = p + bl.realSize;
+
+ p = whitespace(p, pend, bl);
+
+ if(pend - p >= 6) {
+ switch(bl.bytes[p++]) {
+ case 'i':
+ case 'I':
+ switch(bl.bytes[p++]) {
+ case 'n':
+ case 'N':
+ switch(bl.bytes[p++]) {
+ case 's':
+ case 'S':
+ switch(bl.bytes[p++]) {
+ case 'e':
+ case 'E':
+ switch(bl.bytes[p++]) {
+ case 'r':
+ case 'R':
+ switch(bl.bytes[p++]) {
+ case 't':
+ case 'T':
+ return recv.getRuntime().getTrue();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return recv.getRuntime().getFalse();
+ }
+
+ public static IRubyObject select_p(IRubyObject recv, IRubyObject _sql) {
+ ByteList bl = _sql.convertToString().getByteList();
+
+ int p = bl.begin;
+ int pend = p + bl.realSize;
+
+ p = whitespace(p, pend, bl);
+
+ if(pend - p >= 6) {
+ if(bl.bytes[p] == '(') {
+ p++;
+ p = whitespace(p, pend, bl);
+ }
+ if(pend - p >= 6) {
+ switch(bl.bytes[p++]) {
+ case 's':
+ case 'S':
+ switch(bl.bytes[p++]) {
+ case 'e':
+ case 'E':
+ switch(bl.bytes[p++]) {
+ case 'l':
+ case 'L':
+ switch(bl.bytes[p++]) {
+ case 'e':
+ case 'E':
+ switch(bl.bytes[p++]) {
+ case 'c':
+ case 'C':
+ switch(bl.bytes[p++]) {
+ case 't':
+ case 'T':
+ return recv.getRuntime().getTrue();
+ }
+ }
+ }
+ }
+ case 'h':
+ case 'H':
+ switch(bl.bytes[p++]) {
+ case 'o':
+ case 'O':
+ switch(bl.bytes[p++]) {
+ case 'w':
+ case 'W':
+ return recv.getRuntime().getTrue();
+ }
+ }
+ }
+ }
+ }
+ }
+ return recv.getRuntime().getFalse();
+ }
+
private static ResultSet intoResultSet(IRubyObject inp) {
return (ResultSet)((inp instanceof JavaObject ? ((JavaObject)inp) : (((JavaObject)(inp.getInstanceVariable("@java_object"))))).getValue());
}
_______________________________________________
Jruby-extras-devel mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/jruby-extras-devel