-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSQLHelper.java
More file actions
196 lines (160 loc) · 6.29 KB
/
Copy pathSQLHelper.java
File metadata and controls
196 lines (160 loc) · 6.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package dao;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
/** Classe Android para criação de banco de dados que permite Upgrade e Downgrade do banco de dados sem perder os dados.
* @author Arthur Assuncao
* @license Creative Commons3 <http://creativecommons.org/licenses/by-sa/3.0/deed.pt_BR>
* @see SQLiteOpenHelper
*/
public class SQLHelper extends SQLiteOpenHelper {
private String[] tabelas;
private String[] create;
private String[] tabelasRemovidas;
private final String sufixoTabelaTemp = "_temp";
public SQLHelper(Context context, String name, int version, String[] tabelas, String[] create, String[] tabelasRemovidas) {
super(context, name, null, version);
this.tabelas = tabelas; //vetor de tabelas
this.create = create; //vetor de comando CREATE TABLE tabela(campos)
this.tabelasRemovidas = tabelasRemovidas; //vetor com as tabelas que foram removidas do banco
}
@Override
public void onCreate(SQLiteDatabase db) {
//apaga as tabelas que forma removidas do banco
for(String tabelaRemovida : tabelasRemovidas){
apagaTabela(db, tabelaRemovida);
}
//crias as tabelas
for(int i = 0; i < create.length; i++){
db.execSQL(create[i]);
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
recriaBanco(db, oldVersion, newVersion);
}
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
recriaBanco(db, oldVersion, newVersion);
}
// recria o banco com os dados existentes
private void recriaBanco(SQLiteDatabase db, int oldVersion, int newVersion){
//cria tabelas temp e apaga tabelas
for(String tabela : tabelas){
if(tabelaExists(db, tabela)){
criaTabelaTemp(db, tabela);
apagaTabela(db, tabela);
}
}
//cria uma nova base de dados
onCreate(db);
//repopula tabelas
for(String tabela : tabelas){
if(tabelaExists(db, tabela + sufixoTabelaTemp)){
try{
repopula(db, tabela);
}
catch(SQLiteException e){
Log.d("Excecao ao repopupar banco: ", e.getMessage());
apagaRegistrosTabela(db, tabela);
Log.d("Registros removidos: ", String.format("Tabela %s", tabela));
}
apagaTabelaTemp(db, tabela);
}
}
}
private void apagaRegistrosTabela(SQLiteDatabase db, String tabela){
db.execSQL(String.format("DELETE FROM %s", tabela));
}
// apaga uma tabela
private void apagaTabela(SQLiteDatabase db, String tabela){
db.execSQL(String.format("DROP TABLE IF EXISTS %s", tabela));
}
// apaga a tabela temp
private void apagaTabelaTemp(SQLiteDatabase db, String tabela){
apagaTabela(db, tabela + sufixoTabelaTemp);
}
// cria a tabela temp, adicionao o sufixo sufixoTabelaTemp ao nome da tabela
private void criaTabelaTemp(SQLiteDatabase db, String tabela){
String tabelaTemp = String.format("%s%s", tabela, sufixoTabelaTemp);
String queryCriaTabelaTemp = String.format("CREATE TABLE %s AS SELECT * FROM %s", tabelaTemp, tabela);
db.execSQL(queryCriaTabelaTemp);
}
//pega os indices das colunas
private int[] getIndicesColunas(Cursor cursorSelect){
String[] nomeColunas = cursorSelect.getColumnNames();
int[] indices = new int[nomeColunas.length];
for(int i = 0; i < indices.length; i++){
indices[i] = cursorSelect.getColumnIndex(nomeColunas[i]);
}
return indices;
}
//cria uma String com o comando Insert
private String createInsertString(int[] indices, String tabela, Cursor cursorDadosTabelaTemp, Cursor cursorTabelaNova){
StringBuilder colunasTemp = new StringBuilder(); // (col1, col2, col...)
StringBuilder values = new StringBuilder(); // (?, ?, ?...)
for(int indice : indices){
String coluna = cursorDadosTabelaTemp.getColumnName(indice);
// Verifica se a coluna de temp existe na da nova estrutura da tabela
if(cursorTabelaNova.getColumnIndex(coluna) != -1){
colunasTemp.append(coluna + ",");
values.append("?,");
}
}
// Apaga a ultima virgula
colunasTemp.deleteCharAt(colunasTemp.length()-1);
values.deleteCharAt(values.length()-1);
String queryInsert = String.format("INSERT INTO %s(%s) values(%s)", tabela, colunasTemp, values);
return queryInsert;
}
//retorna os valores do cursor
private String[] getValoresCursor(int[] indices, Cursor cursorDadosTabelaTemp, Cursor cursorTabelaNova){
List<String> valoresTemp = new ArrayList<String>(); // valor1, valor2, valor...
for(int indice : indices){
String valor = cursorDadosTabelaTemp.getString(indice); //pega tudo como String
String coluna = cursorDadosTabelaTemp.getColumnName(indice);
// Verifica se a coluna de temp existe na da nova estrutura da tabela
if(cursorTabelaNova.getColumnIndex(coluna) != -1){
valoresTemp.add(valor);
}
}
return valoresTemp.toArray(valoresTemp.toArray(new String[valoresTemp.size()]));
}
//repopula a tabela usando os dados da tabela temporaria
private void repopula(SQLiteDatabase db, String tabela) throws SQLiteException{
Cursor cursorDadosTabelaTemp = db.rawQuery(String.format("SELECT * FROM %s%s", tabela, sufixoTabelaTemp), null);
Cursor cursorTabelaNova = db.rawQuery(String.format("SELECT * FROM %s", tabela), null);
int[] indices = getIndicesColunas(cursorDadosTabelaTemp);
// itera pelos valores da tabela e adiciona ao ao List
if(cursorDadosTabelaTemp.moveToFirst()){
// cria a string para insert, algo como: INSERT INTO tabela(col1, col2) values(?, ?)
String queryInsert = createInsertString(indices, tabela, cursorDadosTabelaTemp, cursorTabelaNova);
do{
// pega os valores das colunas
String[] valoresTemp = getValoresCursor(indices, cursorDadosTabelaTemp, cursorTabelaNova);
// Insere os dados da tabela temp na nova tabela
db.execSQL(queryInsert, valoresTemp);
}while(cursorDadosTabelaTemp.moveToNext());
}
}
//verifica se a tabela existe
private boolean tabelaExists(SQLiteDatabase db, String tabela){
boolean tabelaExiste = false;
try{
@SuppressWarnings("unused")
Cursor cursor = db.query(tabela, null, null, null, null, null, null);
tabelaExiste = true;
}
catch (SQLiteException e){
if (e.getMessage().toString().contains("no such table")){
tabelaExiste = false;
}
}
return tabelaExiste;
}
}