Javascript & Java have different regular expressions, so if you are running
your stuff on desktop browsers in Hosted Mode but compiled mode in Android,
then you might be running into that problem.
A performance improvement should be:
String statement = new String( sqlStatement );
StringBuffer sb = new StringBuffer(statement.length());
int index;
int previous = 0;
int i = 0;
while ((index = statement.indexOf('?')) != -1)
{
String firstPart = statement.substring( previous, index );
sb.append (firstPart).append('"').append(params[i++]).append('"');
previous = index + 1;
}
return sb.toString();
or try
String statement = new String( sqlStatement );
String [] parts = statement.split("[?]");
StringBuffer sb = new StringBuffer(statement.length + parts.length *
AVERAGE_PARAM_LENGTH);
for (int i = 0; i < parts.length; i++)
{
sb.append(parts[i]).append('"').append(params[i]).append('"')
}
AVERAGE_PARAM_LENGTH can be anything, but you want the resultant expression
to be as close as possible to the actual final length as possible, without
going under (assuming this portion of code is your hotpath - otherwise, you
won't notice the difference).
On Thu, May 7, 2009 at 2:12 PM, Evan Ruff <[email protected]> wrote:
>
> Ok so something really fishy is going on with the Gears API.
>
> I created my own "prepareSQLStatement" that converts the SQL Call and
> parameter list into a string.
>
> private String prepareSQLStatement( String sqlStatement, String[]
> params ) throws DatabaseException
> {
> try
> {
> String statement = new String( sqlStatement );
>
> for ( int i = 0; ( statement.indexOf( "?" ) > 0 );
> i++ )
> {
> int index = statement.indexOf( '?' );
> String firstPart = statement.substring( 0,
> index );
> String secondPart = statement.substring(
> index + 1 );
>
> StringBuffer sb = new StringBuffer();
> sb.append( firstPart ).append( "\""
> ).append( params[ i ] ).append
> ( "\"" ).append( secondPart );
> statement = sb.toString();
> }
>
> return statement;
> }
> catch ( IndexOutOfBoundsException indexOut )
> {
> throw new DatabaseException( "Index out of bounds.
> SQL Parameter
> Error" );
> }
> }
>
> When I use this method to prepare the statement before hitting
> db.execute, all of my sql statements work as expected.
>
> Could Android implement it's string manipulation stack slightly
> differently than all the other platforms? I've got a sneaky suspecion
> that the RegExp that's used to parse the '?' in the SQL commands might
> be failing?
>
> Furthermore, can anyone give me an ideas as how to improve the
> performance of the above method? It creates a noticable delay. Did I
> read somewhere that GWT has a slow string manipulation engine?
>
> E
>
>
> On May 6, 2:07 pm, Evan Ruff <[email protected]> wrote:
> > Hey Eric,
> >
> > I'm pretty much terrified of Javascript.
> >
> > I'm a little hesitant to make any determination whatsoever as to the
> > cause of the problem. When I run the GWT Gears Sample DatabaseDemo
> > project, it works as expected. I can even replace all of the DB
> > specifics with the internals of my tables/queries and it seems to
> > work! It's just so freakin' frustrating.
> >
> > RememberTheMilk and the mobile GMail seem to make use of Gears on
> > Android without issue, so I really don't know where to go from here.
> > Any other suggestions?
> >
> > Here's the replaced DatabaseDemo code, fwiw:
> >
> > public class Gears implements EntryPoint
> > {
> > private static final int NUM_SAVED_ROWS = 3;
> > private static final int NUM_DATA_TABLE_COLUMNS = 3;
> >
> > private final Button addButton = new Button( "Add" );
> > private final Button clearButton = new Button( "Clear Database"
> );
> > private Database db;
> > private final TextBox input = new TextBox();
> > private final FlexTable dataTable = new FlexTable();
> >
> > public void onModuleLoad()
> > {
> > VerticalPanel outerPanel = new VerticalPanel();
> > outerPanel.setSpacing( 10 );
> > outerPanel.getElement().getStyle().setPropertyPx(
> "margin", 15 );
> >
> > HorizontalPanel textAndButtonsPanel = new
> HorizontalPanel();
> > textAndButtonsPanel.add( new Label( "Enter a Phrase: " )
> );
> > textAndButtonsPanel.add( input );
> > textAndButtonsPanel.add( addButton );
> > textAndButtonsPanel.add( clearButton );
> > outerPanel.add( textAndButtonsPanel );
> > outerPanel.add( new Label( "Last 3 Entries:" ) );
> > outerPanel.add( dataTable );
> >
> > for ( int i = 0; i <= NUM_SAVED_ROWS; ++i )
> > {
> > dataTable.insertRow( i );
> > for ( int j = 0; j < NUM_DATA_TABLE_COLUMNS; j++
> )
> > {
> > dataTable.addCell( i );
> > }
> > }
> > dataTable.setWidget( 0, 0, new HTML( "<b>Id</b>" ) );
> > dataTable.setWidget( 0, 1, new HTML( "<b>Phrase</b>" ) );
> > dataTable.setWidget( 0, 2, new HTML( "<b>Timestamp</b>" )
> );
> >
> > // Create the database if it doesn't exist.
> > try
> > {
> > db = Factory.getInstance().createDatabase();
> > db.open( "database-demo" );
> >
> > db.execute( "DROP TABLE IF EXISTS user" );
> > db.execute( "CREATE TABLE IF NOT EXISTS user (
> user_id TEXT NOT
> > NULL, sessionId TEXT, name TEXT, email TEXT )" );
> > }
> > catch ( DatabaseException e )
> > {
> > RootPanel.get( "demo" ).add( new HTML( "Error
> opening or creating
> > database: <font color=\"red\">" + e.toString() + "</font>" ) );
> > // Fatal error. Do not build the interface.
> > return;
> > }
> >
> > input.addKeyboardListener( new KeyboardListenerAdapter()
> > {
> > @Override
> > public void onKeyDown( Widget sender, char
> keyCode, int modifiers )
> > {
> > if (keyCode ==
> KeyboardListener.KEY_ENTER)
> > {
> > insertPhrase();
> > }
> > }
> > } );
> >
> > addButton.addClickListener( new ClickListener()
> > {
> > public void onClick( Widget sender )
> > {
> > insertPhrase();
> > }
> > } );
> >
> > clearButton.addClickListener( new ClickListener()
> > {
> > public void onClick( Widget sender )
> > {
> > clearPhrases();
> > displayRecentPhrases();
> > }
> > } );
> >
> > RootPanel.get( "demo" ).add( outerPanel );
> > displayRecentPhrases();
> > }
> >
> > /**
> > * Remove all phrases from the database.
> > */
> > private void clearPhrases()
> > {
> > try
> > {
> > db.execute( "DELETE FROM Phrases" );
> > }
> > catch ( DatabaseException e )
> > {
> > Window.alert( e.toString() );
> > }
> > }
> >
> > /**
> > * Fill the labels with the phrases from the database.
> > */
> > private void displayRecentPhrases()
> > {
> > try
> > {
> > ResultSet rs = db.execute( "SELECT name, email
> FROM user" );
> > int i;
> >
> > for ( i = 1; rs.isValidRow(); ++i, rs.next() )
> > {
> > if (i <= NUM_SAVED_ROWS)
> > {
> > dataTable.setText( i, 0, i+"" );
> > dataTable.setText( i, 1,
> rs.getFieldAsString( 0 ) );
> > dataTable.setText( i, 2, new
> Date( rs.getFieldAsLong
> > ( 1 ) ).toString() );
> > }
> > else
> > {
> > db.execute( "DELETE FROM user" );
> > }
> > }
> > // If a phrase has been removed, clear the label.
> > for ( ; i <= NUM_SAVED_ROWS; i++ )
> > {
> > for ( int j = 0; j <
> NUM_DATA_TABLE_COLUMNS; j++ )
> > {
> > dataTable.clearCell( i, j );
> > }
> > }
> > rs.close();
> > }
> > catch ( DatabaseException e )
> > {
> > Window.alert( e.toString() );
> > }
> > }
> >
> > /**
> > * Add a new phrase to the database.
> > */
> > private void insertPhrase()
> > {
> > try
> > {
> > this.db.execute( "INSERT INTO user (user_id,
> sessionId, name,
> > email) values ( ?, ?, ?, ? )" , new String[] { "stupid", "fake",
> > "shit", "balls" } );
> >
> > displayRecentPhrases();
> > input.setText( "" );
> > }
> > catch ( DatabaseException e )
> > {
> > Window.alert( e.toString() );
> > }
> > }
> >
> > On May 6, 1:47 pm, Eric Ayers <[email protected]> wrote:
> >
> > > If it turns out to be reproducible outside of GWT, I was going to point
> you
> > > at the android-developers google group.
> http://groups.google.com/group/android-developers
> >
> > > On Wed, May 6, 2009 at 1:45 PM, Eric Ayers <[email protected]> wrote:
> > > > I looked at your code and didn't see anything obviously wrong. I
> searched
> > > > on some of the Gears groups and found a similar report, but no
> answer.
> >
> > > > It is worth nothing that the version of Gears on android is different
> > > > (older) than the version you are getting when you install Gears on a
> desktop
> > > > browser. Can we rule out the GWT bindings? Could you write a simple
> > > > program that reproduces (or fails to reproduce) the problem in
> straight
> > > > JavaScript?
> >
> > > > -Eric.
> > > > --
> > > > Eric Z. Ayers - GWT Team - Atlanta, GA USA
> > > >http://code.google.com/webtoolkit/
> >
> > > --
> > > Eric Z. Ayers - GWT Team - Atlanta, GA USAhttp://
> code.google.com/webtoolkit/
> >
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Google Web Toolkit" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/Google-Web-Toolkit?hl=en
-~----------~----~----~----~------~----~------~--~---