Package org.cruxframework.crux.core.client.db

Source Code of org.cruxframework.crux.core.client.db.WSQLAbstractDatabase$SQLCallback

/*
* Copyright 2013 cruxframework.org.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.cruxframework.crux.core.client.db;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.cruxframework.crux.core.client.collection.Array;
import org.cruxframework.crux.core.client.collection.CollectionFactory;
import org.cruxframework.crux.core.client.db.Transaction.Mode;
import org.cruxframework.crux.core.client.db.websql.SQLDatabase;
import org.cruxframework.crux.core.client.db.websql.SQLDatabaseFactory;
import org.cruxframework.crux.core.client.db.websql.SQLError;
import org.cruxframework.crux.core.client.db.websql.SQLResultSet;
import org.cruxframework.crux.core.client.db.websql.SQLTransaction;
import org.cruxframework.crux.core.client.db.websql.SQLTransaction.SQLStatementErrorCallback;
import org.cruxframework.crux.core.client.utils.JsUtils;
import org.cruxframework.crux.core.client.utils.StringUtils;

import com.google.gwt.core.client.JsArrayMixed;
import com.google.gwt.logging.client.LogConfiguration;

/**
* HTML5 AbstractDatabase based on Web SQL (http://www.w3.org/TR/webdatabase/).
* @author Thiago da Rosa de Bustamante
*
*/
public abstract class WSQLAbstractDatabase extends AbstractDatabase
{
  private static int  DEFAULT_DB_SIZE = 5 * 1024 * 1024;
  private static boolean initialized = false;
  private static SQLDatabase systemDatabase;
  protected static Logger logger = Logger.getLogger(WSQLAbstractDatabase.class.getName());

  protected boolean opened = false;
  protected SQLDatabase database;
  protected Array<String> objectStoreNames;
 
  private static final void init(final SQLCallback callback)
  {
    if (!initialized)
    {
      systemDatabase = SQLDatabaseFactory.openDatabase("__sysdb__", "System Database", DEFAULT_DB_SIZE);
      systemDatabase.transaction(new SQLDatabase.SQLTransactionCallback()
      {
       
        @Override
        public void onTransaction(SQLTransaction tx)
        {
          String sql = "CREATE TABLE IF NOT EXISTS dbVersions (name VARCHAR(255), version INT)";
          if (LogConfiguration.loggingIsEnabled())
          {
            logger.log(Level.FINE, "Running SQL ["+sql+"]");
          }
          JsArrayMixed args = JsArrayMixed.createArray().cast();
          tx.executeSQL(sql, args, new SQLTransaction.SQLStatementCallback()
          {
            @Override
            public void onSuccess(SQLTransaction tx, SQLResultSet rs)
            {
              initialized = true;
              if (LogConfiguration.loggingIsEnabled())
              {
                logger.log(Level.INFO, "System table created.");
              }
              callback.onSuccess();
            }
          }, null);
        }
      }, new SQLDatabase.SQLTransactionErrorCallback()
      {
       
        @Override
        public void onError(SQLError error)
        {
          throw new DatabaseException("Could not create the systam table (__sysdb__). Error ["+error.getName()+"]. Message ["+error.getMessage()+"]");
        }
      }, null);
    }
  }
 
  @Override
  public void close()
  {
    if (isOpen())
    {
      opened = false;
    }
  }
 
    @Override
  public void delete(final DatabaseCallback callback)
  {
    if (StringUtils.isEmpty(getName()))
    {
      throw new DatabaseException(messages.databaseInvalidNameDBError(getName()));
    }
    if (!initialized)
    {
      init(new SQLCallback()
      {
        @Override
        public void onSuccess()
        {
          doDelete(callback);
        }
      });
    }
    else
    {
      doDelete(callback);
    }
  }   

    @Override
    public boolean isOpen()
    {
      return opened;
    }

    @Override
    public boolean isSupported()
    {
        return SQLDatabaseFactory.isSupported();
    }
   
    @Override
    protected Transaction createTransaction(String[] storeNames, Mode mode)
    {
      return new WSQLTransaction(this, storeNames, mode);
    }
   
    @Override
  protected void doOpen(final DatabaseCallback callback)
    {
    if (!initialized)
    {
      init(new SQLCallback()
      {
        @Override
        public void onSuccess()
        {
          openDB(callback);
        }
      });
    }
    else
    {
      openDB(callback);
    }
    }     
     
    private void openDB(final DatabaseCallback callback)
    {
    final SQLTransaction.SQLStatementErrorCallback errorCallback = new SQLTransaction.SQLStatementErrorCallback()
    {
      @Override
      public boolean onError(SQLTransaction tx, SQLError error)
      {
        if (LogConfiguration.loggingIsEnabled())
        {
          logger.log(Level.SEVERE, messages.databaseOpenError(getName(), error.getName()+"-"+error.getMessage()));
        }
        if (callback != null)
        {
          callback.onError(messages.databaseOpenError(getName(), error.getName()+"-"+error.getMessage()));
        }
        else if (errorHandler != null)
        {
          errorHandler.onError(messages.databaseOpenError(getName(), error.getName()+"-"+error.getMessage()));
        }       
        return true;
      }
    };
   
    systemDatabase.transaction(new SQLDatabase.SQLTransactionCallback()
    {
      @Override
      public void onTransaction(SQLTransaction tx)
      {
        String sql = "SELECT * FROM dbVersions WHERE name = ?";
        if (LogConfiguration.loggingIsEnabled())
        {
          logger.log(Level.FINE, "Running SQL ["+sql+"]");
        }
        final JsArrayMixed args = JsArrayMixed.createArray().cast();
        args.push(name);
        tx.executeSQL(sql, args, new SQLTransaction.SQLStatementCallback()
        {
          @Override
          public void onSuccess(SQLTransaction tx, SQLResultSet rs)
          {
            if (rs.getRows().length() > 0)
            {
              JsArrayMixed output = JsArrayMixed.createArray().cast();
              JsUtils.readPropertyValue(rs.getRows().itemObject(0), "version", output);
              doOpenDB((int) output.getNumber(0), callback, errorCallback);
            }
            else
            {
              String sql = "INSERT INTO dbVersions VALUES (?,?)";
              if (LogConfiguration.loggingIsEnabled())
              {
                logger.log(Level.FINE, "Running SQL ["+sql+"]");
              }
              args.push(version);
              tx.executeSQL(sql, args, new SQLTransaction.SQLStatementCallback()
              {
                @Override
                public void onSuccess(SQLTransaction tx, SQLResultSet rs)
                {
                  doOpenDB(0, callback, errorCallback);
                }
              }, errorCallback);
            }
          }
        }, errorCallback);
      }
    }, null, null);
  }
   
  private void doOpenDB(final int oldVersion, final DatabaseCallback callback, final SQLTransaction.SQLStatementErrorCallback errorCallback)
    {
      if (version <=0 || oldVersion > version)
      {
        callback.onError("Data Error - An attempt was made to open a database using a lower version than the existing version.");
        return;
      }
      database = SQLDatabaseFactory.openDatabase(name, name, DEFAULT_DB_SIZE);
      database.transaction(new SQLDatabase.SQLTransactionCallback()
    {
     
      @Override
      public void onTransaction(SQLTransaction tx)
      {
        String sql = "CREATE TABLE IF NOT EXISTS __sys__ (name VARCHAR(255))";
        if (LogConfiguration.loggingIsEnabled())
        {
          logger.log(Level.FINE, "Running SQL ["+sql+"]");
        }
        JsArrayMixed args = JsArrayMixed.createArray().cast();
        tx.executeSQL(sql, args, new SQLTransaction.SQLStatementCallback()
        {
          @Override
          public void onSuccess(SQLTransaction tx, SQLResultSet rs)
          {
            loadObjectStoreNames(new SQLCallback()
            {
              @Override
              public void onSuccess()
              {
                if (oldVersion < version)
                {
                  updateDBVersionAndOpen(oldVersion, callback, errorCallback);
                }
                else
                {
                  if (LogConfiguration.loggingIsEnabled())
                  {
                    logger.log(Level.INFO, messages.databaseOpened(getName()));
                  }
                  opened = true;
                  callback.onSuccess();
                }
              }
            });
          }
        }, errorCallback);
      }
    }, null, null);
    }

    private void loadObjectStoreNames(final SQLCallback callback)
    {
      database.transaction(new SQLDatabase.SQLTransactionCallback()
    {
      @Override
      public void onTransaction(final SQLTransaction tx)
      {
        String sql = "SELECT * FROM __sys__";
        if (LogConfiguration.loggingIsEnabled())
        {
          logger.log(Level.FINE, "Running SQL ["+sql+"]");
        }
        final JsArrayMixed args = JsArrayMixed.createArray().cast();
        tx.executeSQL(sql, args, new SQLTransaction.SQLStatementCallback()
        {
          @Override
          public void onSuccess(SQLTransaction tx, SQLResultSet rs)
          {
            objectStoreNames = CollectionFactory.createArray();
           
            int length = rs.getRows().length();
            for (int i = 0; i < length; i++)
            {
              String objectStoreName = JsUtils.readStringPropertyValue(rs.getRows().itemObject(i), "name");
              objectStoreNames.add(objectStoreName);
            }
           
            callback.onSuccess();
          }
        },new SQLTransaction.SQLStatementErrorCallback()
        {
          @Override
          public boolean onError(SQLTransaction tx, SQLError error)
          {
            if (LogConfiguration.loggingIsEnabled())
            {
              logger.log(Level.SEVERE, messages.databaseOpenError(getName(), error.getName()+"-"+error.getMessage()));
            }
            throw new DatabaseException(messages.databaseOpenError(getName(), error.getName()+"-"+error.getMessage()));
          }
        });
      }
    }, new SQLDatabase.SQLTransactionErrorCallback()
    {
      @Override
      public void onError(SQLError error)
      {
        throw new DatabaseException("Error loading object store names. Error ["+error.getName()+"]. Message ["+error.getMessage()+"]");
      }
    }, null);
    }
   
  private void updateDBVersionAndOpen(final int oldVersion, final DatabaseCallback callback, final SQLTransaction.SQLStatementErrorCallback errorCallback)
    {
        systemDatabase.transaction(new SQLDatabase.SQLTransactionCallback()
        {
          @Override
          public void onTransaction(SQLTransaction tx)
          {
            String sql = "UPDATE dbVersions SET version = ? WHERE name = ?";
            if (LogConfiguration.loggingIsEnabled())
            {
              logger.log(Level.FINE, "Running SQL ["+sql+"]");
            }
            JsArrayMixed args = JsArrayMixed.createArray().cast();
            args.push(version);
            args.push(name);
            tx.executeSQL(sql, args, new SQLTransaction.SQLStatementCallback()
            {
              @Override
              public void onSuccess(SQLTransaction tx, SQLResultSet rs)
              {
                database.transaction(new SQLDatabase.SQLTransactionCallback()
            {
             
              @Override
              public void onTransaction(SQLTransaction tx)
              {
                try
                {
                  updateDatabaseStructure(tx, callback);
                }
                catch (RuntimeException e)
                {
                  if (LogConfiguration.loggingIsEnabled())
                  {
                    logger.log(Level.SEVERE, messages.databaseUpgradeError(getName(), e.getMessage()), e);
                  }
                  throw e;
                }
              }
            }, new SQLDatabase.SQLTransactionErrorCallback()
            {
             
              @Override
              public void onError(SQLError error)
              {
                String message = messages.databaseUpgradeError(getName(), error.getMessage());
                if (LogConfiguration.loggingIsEnabled())
                {
                  logger.log(Level.SEVERE, message);
                }
                throw new DatabaseException(message);
              }
            }, new SQLDatabase.SQLCallback()
            {
              @Override
              public void onSuccess()
              {
                opened = true;
                callback.onSuccess();
              }
            });
              }
            }, errorCallback);
          }
        }, null, null);
   
   
  protected void doDelete(final DatabaseCallback callback)
    {
    final SQLTransaction.SQLStatementErrorCallback errorCallback = getDeleteErrorHandler(callback);
    doDelete(callback, errorCallback);
    }

  protected SQLStatementErrorCallback getDeleteErrorHandler(final DatabaseCallback callback)
    {
      return new SQLTransaction.SQLStatementErrorCallback()
    {
      @Override
      public boolean onError(SQLTransaction tx, SQLError error)
      {
        if (LogConfiguration.loggingIsEnabled())
        {
          logger.log(Level.SEVERE, messages.databaseDeleteError(getName(), error.getName()+"-"+error.getMessage()));
        }
        if (callback != null)
        {
          callback.onError(messages.databaseDeleteError(getName(), error.getName()+"-"+error.getMessage()));
        }
        else if (errorHandler != null)
        {
          errorHandler.onError(messages.databaseDeleteError(getName(), error.getName()+"-"+error.getMessage()));
        }       
        return true;
      }
    };
    }

    protected void doDelete(final DatabaseCallback callback, final SQLTransaction.SQLStatementErrorCallback errorCallback)
    {
      systemDatabase.transaction(new SQLDatabase.SQLTransactionCallback()
    {
      @Override
      public void onTransaction(SQLTransaction tx)
      {
        String sql = "SELECT * FROM dbVersions WHERE name = ?";
        if (LogConfiguration.loggingIsEnabled())
        {
          logger.log(Level.FINE, "Running SQL ["+sql+"]");
        }
        final JsArrayMixed args = JsArrayMixed.createArray().cast();
        args.push(name);
        tx.executeSQL(sql, args, new SQLTransaction.SQLStatementCallback()
        {
          @Override
          public void onSuccess(SQLTransaction tx, SQLResultSet rs)
          {
            if (rs.getRows().length() == 0)
            {
              if (callback != null)
              {
                callback.onSuccess();
              }
                  return;
            }
            deleteDBTables(callback, errorCallback);
          }
        }, errorCallback);
      }
    }, null, null);
    }

  protected void deleteDBTables(SQLTransaction tx, final DatabaseCallback callback, final SQLStatementErrorCallback errorCallback, final boolean removeSystemTables)
  {
    String sql = "SELECT * FROM __sys__";
    if (LogConfiguration.loggingIsEnabled())
    {
      logger.log(Level.FINE, "Running SQL ["+sql+"]");
    }
    final JsArrayMixed args = JsArrayMixed.createArray().cast();
    tx.executeSQL(sql, args, new SQLTransaction.SQLStatementCallback()
    {
      @Override
      public void onSuccess(SQLTransaction tx, SQLResultSet rs)
      {
        int length = rs.getRows().length();
        String sql;
        final JsArrayMixed args = JsArrayMixed.createArray().cast();
        for (int i=0; i< length; i++)
        {
          sql = "DROP TABLE "+JsUtils.readStringPropertyValue(rs.getRows().itemObject(i), "name");
          if (LogConfiguration.loggingIsEnabled())
          {
            logger.log(Level.FINE, "Running SQL ["+sql+"]");
          }
          tx.executeSQL(sql, args, null, errorCallback);
        }
        if (removeSystemTables)
        {
          sql = "DROP TABLE __sys__";
          if (LogConfiguration.loggingIsEnabled())
          {
            logger.log(Level.FINE, "Running SQL ["+sql+"]");
          }
          tx.executeSQL(sql, args, new SQLTransaction.SQLStatementCallback()
          {
            @Override
            public void onSuccess(SQLTransaction tx, SQLResultSet rs)
            {
              deleteFromDbVersions(callback, errorCallback);
            }
          }, errorCallback);
        }
        else
        {
          callback.onSuccess();
        }
      }
    }, errorCallback);
  }
 
  protected void deleteDBTables(final DatabaseCallback callback, final SQLStatementErrorCallback errorCallback)
  {
      final SQLDatabase database = SQLDatabaseFactory.openDatabase(name, name, DEFAULT_DB_SIZE);
      database.transaction(new SQLDatabase.SQLTransactionCallback()
    {
      @Override
      public void onTransaction(final SQLTransaction tx)
      {
        deleteDBTables(tx, callback, errorCallback, true);
      }
    }, null, null);
  }
 
  protected void deleteFromDbVersions(final DatabaseCallback callback, final SQLStatementErrorCallback errorCallback)
  {
    systemDatabase.transaction(new SQLDatabase.SQLTransactionCallback()
    {
      @Override
      public void onTransaction(SQLTransaction tx)
      {
        String sql = "DELETE FROM dbVersions WHERE name = ? ";
        if (LogConfiguration.loggingIsEnabled())
        {
          logger.log(Level.FINE, "Running SQL ["+sql+"]");
        }
        final JsArrayMixed args = JsArrayMixed.createArray().cast();
        args.push(name);
        tx.executeSQL(sql, args, new SQLTransaction.SQLStatementCallback()
        {
          @Override
          public void onSuccess(SQLTransaction tx, SQLResultSet rs)
          {
            callback.onSuccess();
          }
        }, errorCallback);
      }
    }, null, null);
  }   
 
  protected void createFileStore(SQLTransaction tx)
  {
    final SQLTransaction.SQLStatementErrorCallback errorCallback = new SQLTransaction.SQLStatementErrorCallback()
    {
      @Override
      public boolean onError(SQLTransaction tx, SQLError error)
      {
        String message = messages.objectStoreOperationError(error.getName() + " - " + error.getMessage());
        if (LogConfiguration.loggingIsEnabled())
        {
          logger.log(Level.SEVERE, message);
        }
        else if (errorHandler != null)
        {
          errorHandler.onError(message);
        }
        return true;
      }
    };

    String sql = "INSERT INTO __sys__(name) VALUES (?)";
    JsArrayMixed args = JsArrayMixed.createArray().cast();
    args.push(FileStore.OBJECT_STORE_NAME);
    tx.executeSQL(sql, args, new SQLTransaction.SQLStatementCallback()
    {
      @Override
      public void onSuccess(SQLTransaction tx, SQLResultSet rs)
      {
        String sql = "CREATE TABLE \""+FileStore.OBJECT_STORE_NAME+"\" (value BLOB, fileName TEXT PRIMARY KEY)";
        JsArrayMixed args = JsArrayMixed.createArray().cast();
        tx.executeSQL(sql, args, null, errorCallback);
      }
    }, errorCallback);

   
   
  }
 
  protected abstract void updateDatabaseStructure(SQLTransaction tx, DatabaseCallback callback);
  protected abstract <K, V> WSQLAbstractObjectStore<K, V> getObjectStore(String storeName, WSQLTransaction transaction);
 
  static interface SQLCallback
  {
    void onSuccess();
  }
}
TOP

Related Classes of org.cruxframework.crux.core.client.db.WSQLAbstractDatabase$SQLCallback

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.