Oh yeah - didn't notice that you were using StringBuffer. StringBuilder is the appropriate one. I had assumed that sqlStatement was perhaps an array or something - if it's another string, then yes, you do not need to create a copy like that since they are immutable.
The while loop instead of for loop shouldn't save him anything in this case. On Thu, May 7, 2009 at 2:42 PM, Eric Ayers <[email protected]> wrote: > Your best bet for android specific stuff would be to ask on the > android-users group. Here are some general observations inline: > > 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 ); > > > performance: There's no need to make a copy of the string here. Strings > are immutable. > > >> >> >> for ( int i = 0; ( statement.indexOf( "?" ) > 0 ); >> i++ ) > > > You probably want a while loop here: while(statement.indexOf("?") > 0) { > ... } > > >> >> { >> int index = statement.indexOf( '?' ); >> String firstPart = statement.substring( 0, >> index ); >> String secondPart = statement.substring( >> index + 1 ); >> >> StringBuffer sb = new StringBuffer(); > > > performance: Try using StringBuilder instead of StringBuffer. > http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html > > >> >> sb.append( firstPart ).append( "\"" >> ).append( params[ i ] ).append >> ( "\"" ).append( secondPart ); >> statement = sb.toString(); > > > performance: I don't know how big your SQL statement is or how many > parameters you have, but you are scanning it over and over from the > beginning of the string. You really only need to analyze it from the end if > the previous indexOf() line. > > >> >> } >> >> 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/ >> >> > > > -- > Eric Z. Ayers - GWT Team - Atlanta, GA USA > http://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 -~----------~----~----~----~------~----~------~--~---
