Back to project page LitePal.
The source code is released under:
Apache License
If you think the Android project LitePal listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/* * Copyright (C) Tony Green, Litepal Framework Open Source Project */*from w w w . j a v a 2 s . c o m*/ * 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.litepal.tablemanager; import java.util.ArrayList; import java.util.Collection; import org.litepal.LitePalBase; import org.litepal.exceptions.DatabaseGenerateException; import org.litepal.parser.LitePalAttr; import org.litepal.tablemanager.model.AssociationsModel; import org.litepal.tablemanager.model.TableModel; import org.litepal.util.BaseUtility; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; /** * This class is the basic class for managing database dynamically. It is used * to create or update tables by the mapping classes from litepal.xml file. * Generator is a superclass, it just read the fields from classes and format * the fields types into database types. The analysis job is delegated to the * subclasses to do. Then subclasses can invoke the execute method to finish the * job or they can override to do their own logic. * * @author Tony Green * @since 1.0 */ public abstract class Generator extends LitePalBase { public static final String TAG = "Generator"; /** * The collection contains all table models. Use a global variable store * table model to improve performance. Avoiding look up for table model each * time. */ private Collection<TableModel> mTableModels; /** * The collection contains all association models. */ private Collection<AssociationsModel> mAllRelationModels; /** * This is a shortcut way to get all the table models for each model class * defined in the mapping list. No need to iterate all the model classes and * get table model for each one. * * @return A collection contains all table models. */ protected Collection<TableModel> getAllTableModels() { if (mTableModels == null) { mTableModels = new ArrayList<TableModel>(); } if (!canUseCache()) { mTableModels.clear(); for (String className : LitePalAttr.getInstance().getClassNames()) { mTableModels.add(getTableModel(className)); } } return mTableModels; } /** * This method is used to get all the association models which in the * mapping list of litepal.xml file. * * @return Collection of RelationModel for all the mapping classes. * * @throws DatabaseGenerateException */ protected Collection<AssociationsModel> getAllAssociations() { if (mAllRelationModels == null || mAllRelationModels.isEmpty()) { mAllRelationModels = getAssociations(LitePalAttr.getInstance().getClassNames()); } return mAllRelationModels; } /** * Use the parameter SQLiteDatabase to execute the passing SQLs. Subclasses * can add their own logic when do the executing job by overriding this * method. * * @param sqls * SQLs that want to execute. * @param db * instance of SQLiteDatabase * * @throws DatabaseGenerateException */ protected void execute(String[] sqls, SQLiteDatabase db) { String throwSQL = ""; try { if (sqls != null) { for (String sql : sqls) { throwSQL = sql; db.execSQL(BaseUtility.changeCase(sql)); } } } catch (SQLException e) { throw new DatabaseGenerateException(DatabaseGenerateException.SQL_ERROR + throwSQL); } } /** * Add association to all the tables based on the associations between class * models. * * @param db * Instance of SQLiteDatabase. * @param force * Drop the table first if it already exists. */ private static void addAssociation(SQLiteDatabase db, boolean force) { AssociationCreator associationsCreator = new Creator(); associationsCreator.addOrUpdateAssociation(db, force); } /** * Update associations to all the associated tables in the database. Remove * dump foreign key columns and dump intermediate join tables. * * @param db * Instance of SQLiteDatabase. */ private static void updateAssociations(SQLiteDatabase db) { AssociationUpdater associationUpgrader = new Upgrader(); associationUpgrader.addOrUpdateAssociation(db, false); } /** * Upgrade all the tables in the database, including remove dump columns and * add new columns. * * @param db * Instance of SQLiteDatabase. */ private static void upgradeTables(SQLiteDatabase db) { Upgrader upgrader = new Upgrader(); upgrader.createOrUpgradeTable(db, false); } /** * Create tables based on the class models defined in the litepal.xml file. * After the tables are created, add association to these tables based on * the associations between class models. * * @param db * Instance of SQLiteDatabase. * @param force * Drop the table first if it already exists. */ private static void create(SQLiteDatabase db, boolean force) { Creator creator = new Creator(); creator.createOrUpgradeTable(db, force); } /** * Drop the tables which are no longer exist in the mapping list but created * before. * * @param db * Instance of SQLiteDatabase. */ private static void drop(SQLiteDatabase db) { Dropper dropper = new Dropper(); dropper.createOrUpgradeTable(db, false); } /** * If the table models in the collection has the same size as classes * defined in the mapping list, it means that the table models are exist. * Can use cache. * * @return Can use the cache for the table models or not. */ private boolean canUseCache() { if (mTableModels == null) { return false; } return mTableModels.size() == LitePalAttr.getInstance().getClassNames().size(); } /** * Create tables based on the class models defined in the litepal.xml file. * After the tables are created, add association to these tables based on * the associations between class models. * * @param db * Instance of SQLiteDatabase. */ static void create(SQLiteDatabase db) { create(db, true); addAssociation(db, true); } /** * Upgrade tables to make sure when model classes are changed, the * corresponding tables in the database should be always synchronized with * them. * * @param db * Instance of SQLiteDatabase. */ static void upgrade(SQLiteDatabase db) { drop(db); create(db, false); updateAssociations(db); upgradeTables(db); addAssociation(db, false); } /** * Analysis the TableModel by the purpose of subclasses, and generate a SQL * to do the intention job. The implementation of this method is totally * delegated to the subclasses. * * @param db * Instance of SQLiteDatabase. * @param force * Drop the table first if it already exists. */ protected abstract void createOrUpgradeTable(SQLiteDatabase db, boolean force); /** * Analysis the {@link AssociationsModel} by the purpose of subclasses, and * generate a SQL to do the intention job. The implementation of this method * is totally delegated to the subclasses. * * @param db * Instance of SQLiteDatabase. * @param force * Drop the table first if it already exists. */ protected abstract void addOrUpdateAssociation(SQLiteDatabase db, boolean force); }