/*
|
*
|
* * Copyright (C) 2019 Amit Shekhar
|
* * Copyright (C) 2011 Android Open Source Project
|
* *
|
* * 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 com.amitshekhar.utils;
|
|
import android.content.ContentValues;
|
import android.database.Cursor;
|
import android.text.TextUtils;
|
|
import com.amitshekhar.model.Response;
|
import com.amitshekhar.model.RowDataRequest;
|
import com.amitshekhar.model.TableDataResponse;
|
import com.amitshekhar.model.UpdateRowResponse;
|
import com.amitshekhar.sqlite.SQLiteDB;
|
|
import java.util.ArrayList;
|
import java.util.HashSet;
|
import java.util.List;
|
|
/**
|
* Created by amitshekhar on 06/02/17.
|
*/
|
public class DatabaseHelper {
|
private DatabaseHelper() {
|
// This class in not publicly instantiable
|
}
|
|
public static Response getAllTableName(SQLiteDB database) {
|
Response response = new Response();
|
Cursor c = database.rawQuery("SELECT name FROM sqlite_master WHERE type='table' OR type='view' ORDER BY name COLLATE NOCASE", null);
|
if (c.moveToFirst()) {
|
while (!c.isAfterLast()) {
|
response.rows.add(c.getString(0));
|
c.moveToNext();
|
}
|
}
|
c.close();
|
response.isSuccessful = true;
|
try {
|
response.dbVersion = database.getVersion();
|
} catch (Exception ignore) {
|
}
|
return response;
|
}
|
|
public static TableDataResponse getTableData(SQLiteDB db, String selectQuery, String tableName) {
|
TableDataResponse tableData = new TableDataResponse();
|
tableData.isSelectQuery = true;
|
if (tableName == null) {
|
tableName = getTableName(selectQuery);
|
}
|
final String quotedTableName = getQuotedTableName(tableName);
|
if (tableName != null) {
|
final String pragmaQuery = "PRAGMA table_info(" + quotedTableName + ")";
|
tableData.tableInfos = getTableInfo(db, pragmaQuery);
|
}
|
Cursor cursor = null;
|
boolean isView = false;
|
try {
|
cursor = db.rawQuery("SELECT type FROM sqlite_master WHERE name=?",
|
new String[]{quotedTableName});
|
if (cursor.moveToFirst()) {
|
isView = "view".equalsIgnoreCase(cursor.getString(0));
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
} finally {
|
if (cursor != null) {
|
cursor.close();
|
}
|
}
|
tableData.isEditable = tableName != null && tableData.tableInfos != null && !isView;
|
if (!TextUtils.isEmpty(tableName)) {
|
selectQuery = selectQuery.replace(tableName, quotedTableName);
|
}
|
try {
|
cursor = db.rawQuery(selectQuery, null);
|
} catch (Exception e) {
|
e.printStackTrace();
|
tableData.isSuccessful = false;
|
tableData.errorMessage = e.getMessage();
|
return tableData;
|
}
|
if (cursor != null) {
|
cursor.moveToFirst();
|
// setting tableInfo when tableName is not known and making
|
// it non-editable also by making isPrimary true for all
|
if (tableData.tableInfos == null) {
|
tableData.tableInfos = new ArrayList<>();
|
for (int i = 0; i < cursor.getColumnCount(); i++) {
|
TableDataResponse.TableInfo tableInfo = new TableDataResponse.TableInfo();
|
tableInfo.title = cursor.getColumnName(i);
|
tableInfo.isPrimary = true;
|
tableData.tableInfos.add(tableInfo);
|
}
|
}
|
tableData.isSuccessful = true;
|
tableData.rows = new ArrayList<>();
|
String[] columnNames = cursor.getColumnNames();
|
List<TableDataResponse.TableInfo> tableInfoListModified = new ArrayList<>();
|
for (String columnName : columnNames) {
|
for (TableDataResponse.TableInfo tableInfo : tableData.tableInfos) {
|
if (columnName.equals(tableInfo.title)) {
|
tableInfoListModified.add(tableInfo);
|
break;
|
}
|
}
|
}
|
if (tableData.tableInfos.size() != tableInfoListModified.size()) {
|
tableData.tableInfos = tableInfoListModified;
|
tableData.isEditable = false;
|
}
|
if (cursor.getCount() > 0) {
|
do {
|
List<TableDataResponse.ColumnData> row = new ArrayList<>();
|
for (int i = 0; i < cursor.getColumnCount(); i++) {
|
TableDataResponse.ColumnData columnData = new TableDataResponse.ColumnData();
|
switch (cursor.getType(i)) {
|
case Cursor.FIELD_TYPE_BLOB:
|
columnData.dataType = DataType.TEXT;
|
columnData.value = ConverterUtils.blobToString(cursor.getBlob(i));
|
break;
|
case Cursor.FIELD_TYPE_FLOAT:
|
columnData.dataType = DataType.REAL;
|
columnData.value = cursor.getDouble(i);
|
break;
|
case Cursor.FIELD_TYPE_INTEGER:
|
columnData.dataType = DataType.INTEGER;
|
columnData.value = cursor.getLong(i);
|
break;
|
case Cursor.FIELD_TYPE_STRING:
|
columnData.dataType = DataType.TEXT;
|
columnData.value = cursor.getString(i);
|
break;
|
default:
|
columnData.dataType = DataType.TEXT;
|
columnData.value = cursor.getString(i);
|
}
|
row.add(columnData);
|
}
|
tableData.rows.add(row);
|
} while (cursor.moveToNext());
|
}
|
cursor.close();
|
return tableData;
|
} else {
|
tableData.isSuccessful = false;
|
tableData.errorMessage = "Cursor is null";
|
return tableData;
|
}
|
}
|
|
private static String getQuotedTableName(String tableName) {
|
return String.format("[%s]", tableName);
|
}
|
|
private static List<TableDataResponse.TableInfo> getTableInfo(SQLiteDB db, String pragmaQuery) {
|
Cursor cursor;
|
try {
|
cursor = db.rawQuery(pragmaQuery, null);
|
} catch (Exception e) {
|
e.printStackTrace();
|
return null;
|
}
|
if (cursor != null) {
|
List<TableDataResponse.TableInfo> tableInfoList = new ArrayList<>();
|
cursor.moveToFirst();
|
if (cursor.getCount() > 0) {
|
do {
|
TableDataResponse.TableInfo tableInfo = new TableDataResponse.TableInfo();
|
for (int i = 0; i < cursor.getColumnCount(); i++) {
|
final String columnName = cursor.getColumnName(i);
|
switch (columnName) {
|
case Constants.PK:
|
tableInfo.isPrimary = cursor.getInt(i) == 1;
|
break;
|
case Constants.NAME:
|
tableInfo.title = cursor.getString(i);
|
break;
|
default:
|
}
|
}
|
tableInfoList.add(tableInfo);
|
} while (cursor.moveToNext());
|
}
|
cursor.close();
|
return tableInfoList;
|
}
|
return null;
|
}
|
|
public static UpdateRowResponse addRow(SQLiteDB db, String tableName,
|
List<RowDataRequest> rowDataRequests) {
|
UpdateRowResponse updateRowResponse = new UpdateRowResponse();
|
if (rowDataRequests == null || tableName == null) {
|
updateRowResponse.isSuccessful = false;
|
return updateRowResponse;
|
}
|
tableName = getQuotedTableName(tableName);
|
ContentValues contentValues = new ContentValues();
|
for (RowDataRequest rowDataRequest : rowDataRequests) {
|
if (Constants.NULL.equals(rowDataRequest.value)) {
|
rowDataRequest.value = null;
|
}
|
switch (rowDataRequest.dataType) {
|
case DataType.INTEGER:
|
contentValues.put(rowDataRequest.title, Long.valueOf(rowDataRequest.value));
|
break;
|
case DataType.REAL:
|
contentValues.put(rowDataRequest.title, Double.valueOf(rowDataRequest.value));
|
break;
|
case DataType.TEXT:
|
contentValues.put(rowDataRequest.title, rowDataRequest.value);
|
break;
|
default:
|
contentValues.put(rowDataRequest.title, rowDataRequest.value);
|
break;
|
}
|
}
|
long result = db.insert(tableName, null, contentValues);
|
updateRowResponse.isSuccessful = result > 0;
|
return updateRowResponse;
|
}
|
|
public static UpdateRowResponse updateRow(SQLiteDB db, String tableName, List<RowDataRequest> rowDataRequests) {
|
UpdateRowResponse updateRowResponse = new UpdateRowResponse();
|
if (rowDataRequests == null || tableName == null) {
|
updateRowResponse.isSuccessful = false;
|
return updateRowResponse;
|
}
|
tableName = getQuotedTableName(tableName);
|
ContentValues contentValues = new ContentValues();
|
String whereClause = null;
|
List<String> whereArgsList = new ArrayList<>();
|
for (RowDataRequest rowDataRequest : rowDataRequests) {
|
if (Constants.NULL.equals(rowDataRequest.value)) {
|
rowDataRequest.value = null;
|
}
|
if (rowDataRequest.isPrimary) {
|
if (whereClause == null) {
|
whereClause = rowDataRequest.title + "=? ";
|
} else {
|
whereClause = whereClause + "and " + rowDataRequest.title + "=? ";
|
}
|
whereArgsList.add(rowDataRequest.value);
|
} else {
|
switch (rowDataRequest.dataType) {
|
case DataType.INTEGER:
|
contentValues.put(rowDataRequest.title, Long.valueOf(rowDataRequest.value));
|
break;
|
case DataType.REAL:
|
contentValues.put(rowDataRequest.title, Double.valueOf(rowDataRequest.value));
|
break;
|
case DataType.TEXT:
|
contentValues.put(rowDataRequest.title, rowDataRequest.value);
|
break;
|
default:
|
}
|
}
|
}
|
String[] whereArgs = new String[whereArgsList.size()];
|
for (int i = 0; i < whereArgsList.size(); i++) {
|
whereArgs[i] = whereArgsList.get(i);
|
}
|
db.update(tableName, contentValues, whereClause, whereArgs);
|
updateRowResponse.isSuccessful = true;
|
return updateRowResponse;
|
}
|
|
public static UpdateRowResponse deleteRow(SQLiteDB db, String tableName,
|
List<RowDataRequest> rowDataRequests) {
|
UpdateRowResponse updateRowResponse = new UpdateRowResponse();
|
if (rowDataRequests == null || tableName == null) {
|
updateRowResponse.isSuccessful = false;
|
return updateRowResponse;
|
}
|
tableName = getQuotedTableName(tableName);
|
String whereClause = null;
|
List<String> whereArgsList = new ArrayList<>();
|
for (RowDataRequest rowDataRequest : rowDataRequests) {
|
if (Constants.NULL.equals(rowDataRequest.value)) {
|
rowDataRequest.value = null;
|
}
|
if (rowDataRequest.isPrimary) {
|
if (whereClause == null) {
|
whereClause = rowDataRequest.title + "=? ";
|
} else {
|
whereClause = whereClause + "and " + rowDataRequest.title + "=? ";
|
}
|
whereArgsList.add(rowDataRequest.value);
|
}
|
}
|
if (whereArgsList.size() == 0) {
|
updateRowResponse.isSuccessful = true;
|
return updateRowResponse;
|
}
|
String[] whereArgs = new String[whereArgsList.size()];
|
for (int i = 0; i < whereArgsList.size(); i++) {
|
whereArgs[i] = whereArgsList.get(i);
|
}
|
db.delete(tableName, whereClause, whereArgs);
|
updateRowResponse.isSuccessful = true;
|
return updateRowResponse;
|
}
|
|
public static TableDataResponse exec(SQLiteDB database, String sql) {
|
TableDataResponse tableDataResponse = new TableDataResponse();
|
tableDataResponse.isSelectQuery = false;
|
try {
|
String tableName = getTableName(sql);
|
if (!TextUtils.isEmpty(tableName)) {
|
String quotedTableName = getQuotedTableName(tableName);
|
sql = sql.replace(tableName, quotedTableName);
|
}
|
database.execSQL(sql);
|
} catch (Exception e) {
|
e.printStackTrace();
|
tableDataResponse.isSuccessful = false;
|
tableDataResponse.errorMessage = e.getMessage();
|
return tableDataResponse;
|
}
|
tableDataResponse.isSuccessful = true;
|
return tableDataResponse;
|
}
|
|
private static String getTableName(String selectQuery) {
|
// TODO: Handle JOIN Query
|
TableNameParser tableNameParser = new TableNameParser(selectQuery);
|
HashSet<String> tableNames = (HashSet<String>) tableNameParser.tables();
|
for (String tableName : tableNames) {
|
if (!TextUtils.isEmpty(tableName)) {
|
return tableName;
|
}
|
}
|
return null;
|
}
|
}
|