/**
* Odoo, Open Source Management Solution
* Copyright (C) 2012-today Odoo SA (<http:www.odoo.com>)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http:www.gnu.org/licenses/>
*
* Created on 31/12/14 3:11 PM
*/
package com.odoo.core.orm;
import android.content.Context;
import android.util.Log;
import com.odoo.core.orm.fields.OColumn;
import com.odoo.core.orm.fields.types.OInteger;
import com.odoo.core.orm.fields.types.OTypeHelper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class OSQLHelper {
public static final String TAG = OSQLHelper.class.getSimpleName();
private Context mContext = null;
private List<String> mModels = new ArrayList<>();
private HashMap<String, String> mSQLStatements = new HashMap<>();
public OSQLHelper(Context context) {
mContext = context;
}
public List<String> getModels() {
return mModels;
}
public void createStatements(OModel model) {
StringBuffer sql = null;
if (!mModels.contains(model.getModelName())) {
mModels.add(model.getModelName());
sql = new StringBuffer();
sql.append("CREATE TABLE IF NOT EXISTS ");
sql.append(model.getTableName());
sql.append(" (");
List<OColumn> columns = model.getColumns();
sql.append(generateColumnStatement(model, columns));
sql.deleteCharAt(sql.lastIndexOf(","));
sql.append(")");
mSQLStatements.put(model.getTableName(), sql.toString());
}
}
private String generateColumnStatement(OModel model, List<OColumn> columns) {
StringBuffer column_statement = new StringBuffer();
List<String> finishedColumns = new ArrayList<>();
for (OColumn column : columns) {
if (!finishedColumns.contains(column.getName())) {
finishedColumns.add(column.getName());
String type = getType(column);
if (type != null) {
column_statement.append(column.getName());
column_statement.append(" " + type + " ");
if (column.isAutoIncrement()) {
column_statement.append(" PRIMARY KEY ");
column_statement.append(" AUTOINCREMENT ");
}
Object default_value = column.getDefaultValue();
if (default_value != null) {
column_statement.append(" DEFAULT ");
if (default_value instanceof String) {
column_statement.append("'" + default_value + "'");
} else {
column_statement.append(default_value);
}
}
column_statement.append(", ");
}
if (column.getRelationType() != null) {
createRelationTable(model, column);
}
}
}
return column_statement.toString();
}
private void createRelationTable(OModel base_model, OColumn column) {
try {
OModel rel_model = base_model.createInstance(column.getType());
switch (column.getRelationType()) {
case ManyToOne:
case OneToMany:
createStatements(rel_model);
break;
case ManyToMany:
manyToManyTable(column, base_model);
// Creating master table for related column
createStatements(base_model.createInstance(column.getType()));
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void manyToManyTable(OColumn column, OModel model) {
StringBuffer sql = null;
try {
OModel relation_model = model.createInstance(column.getType());
List<OColumn> m2mCols = model.getManyToManyColumns(relation_model);
String table_name = model.getTableName() + "_"
+ relation_model.getTableName() + "_rel";
if (!mModels.contains(table_name)) {
sql = new StringBuffer();
mModels.add(table_name);
String col_statement = generateColumnStatement(model, m2mCols);
sql.append("CREATE TABLE IF NOT EXISTS ");
sql.append(table_name);
sql.append(" (");
sql.append(col_statement);
sql.deleteCharAt(sql.lastIndexOf(","));
sql.append(")");
mSQLStatements.put(table_name, sql.toString());
Log.v(TAG, "Table Created : " + table_name);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private String getType(OColumn column) {
try {
if (column.getRelationType() == null) {
if (column.getType().getSuperclass().isAssignableFrom(OTypeHelper.class)) {
OTypeHelper type = (OTypeHelper) column.getType().newInstance();
type.setSize(column.getSize());
return type.getType();
}
} else if (column.getRelationType() == OColumn.RelationType.ManyToOne) {
return new OInteger().getType();
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
e.printStackTrace();
}
return null;
}
public HashMap<String, String> getStatements() {
return mSQLStatements;
}
public void createDropStatements(OModel model) {
StringBuffer sql = null;
try {
if (!mModels.contains(model.getTableName())) {
mModels.add(model.getTableName());
sql = new StringBuffer();
sql.append("DROP TABLE IF EXISTS ");
sql.append(model.getTableName());
mSQLStatements.put(model.getTableName(), sql.toString());
Log.v(TAG, "Table Dropped : " + model.getTableName());
for (OColumn col : model.getColumns()) {
if (col.getRelationType() != null) {
switch (col.getRelationType()) {
case ManyToMany:
OModel rel = model.createInstance(col.getType());
String table_name = model.getTableName() + "_"
+ rel.getTableName() + "_rel";
sql = new StringBuffer();
sql.append("DROP TABLE IF EXISTS ");
sql.append(table_name);
mModels.add(table_name);
mSQLStatements.put(table_name, sql.toString());
Log.v(TAG, "Table Dropped : " + table_name);
break;
case ManyToOne:
case OneToMany:
createDropStatements(model.createInstance(col
.getType()));
break;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public List<OModel> getAllModels(List<OModel> models) {
mModels.clear();
List<OModel> all_models = new ArrayList<>();
for (OModel model : models) {
if (!mModels.contains(model.getModelName())) {
mModels.add(model.getModelName());
all_models.add(model);
// Checks for relation models
List<OModel> relModels = getRelationModels(model, model.getRelationColumns());
all_models.addAll(relModels);
}
}
mModels.clear();
return all_models;
}
private List<OModel> getRelationModels(OModel model, List<OColumn> cols) {
List<OModel> models = new ArrayList<>();
for (OColumn col : cols) {
OModel rel_model = model.createInstance(col.getType());
if (rel_model != null && !mModels.contains(rel_model.getModelName())) {
mModels.add(rel_model.getModelName());
models.add(rel_model);
models.addAll(getRelationModels(rel_model, rel_model.getRelationColumns()));
}
}
return models;
}
}