SWADroid/SWADroid/src/main/java/es/ugr/swad/swadroid/database/DataBaseHelper.java
Javier Bueno López ab0898c571 Indoor Location new module (#287)
* Adding icons and text for manage location

* Adding manage location to main menu

* Adding class to manage location

* Adding view layout to manage location

* Share location switch created

* Basic listener added to switch

* Moving manage location to users menu

* Adding icons and text for manage location

* Adding manage location to main menu

* Adding class to manage location

* Adding view layout to manage location

* Share location switch created

* Basic listener added to switch

* Moving manage location to users menu

* Adding elements to indoor_location view

* Improving indoor_location with default text

* Logic to calculate distance

* Trying to connect to the API.

* Adding model to location distance

* Changing textview to listview

* Making request to MacStore API to get location of Mac

* Search user menu

* New designs manage location activity

* Connecting to swad api

* Connection to swad api working

* Location history showing up in activity

* Adding button and user code to find user

* Sorting locations and saving only one

* Implementing GetLastLocation API method

* Adding location preferences translations

* Adding translations to location menu toast

* Return without error from searching user

* Removing warning

* Adding translations

* Changing permissions

* Changing module name

* Making location serializable

* Changing deprecated implementation

* Cleaning code and refactoring deprecated classes

* Changing location name in menu

* Scanning all wifi networks

* Hiding white activities

* Showing more information in each location

* Fixing bug when searching user

* Fixing available networks sort

* Using roomCode instead of institutionCode

* Changes scheduling tasks

* Deleting dependencies

* Deleting useless import

* Getting correct mac

* Requesting permissions to user

* LocationTimeStamp inherits from Location

* Using new variable to soap object

* Setting const defaultValue

* Extracting common lines on update location click

* Extracting common lines on activity result

* Update SWADroid/src/main/res/values/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values-es/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Using functions to reduce code

* Update SWADroid/src/main/res/values/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/GetLastLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/model/UserFilter.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/GetLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/GetLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/GetLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Constant moved to class level

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/SendCurrentLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/SendCurrentLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/SendCurrentLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/messages/SearchUsers.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values-es/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values-es/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values-es/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values-es/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values-es/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values-es/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values-es/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Adding dependency to preferences

* Changing indoor location title text

* Showing text when no location is found

* Allow always location option

* Adding new button to show mac

* Find mac button added and working

* Stopping scheduler when user can't be located

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/model/LocationTimeStamp.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/model/LocationTimeStamp.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/model/LocationTimeStamp.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/xml/preferences.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update material version to 1.2.1

* Updating plugin

* Fixing API permissions

* Update gradle/wrapper/gradle-wrapper.properties

* Minor code style improvements

* Fix IndexOutOfBoundsException

* Add default locale to SimpleDateFormat

* Use complete Gradle distribution

* Update authors

* Update CHANGELOG

* Remove unused import

* Minor code style improvements

Co-authored-by: javibl8@correo.ugr.es <javier.bueno@jitkey.com>
Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>
2020-10-14 19:50:20 +02:00

2460 lines
89 KiB
Java

/*
* This file is part of SWADroid.
*
* Copyright (C) 2010 Juan Miguel Boyero Corral <juanmi1982@gmail.com>
*
* SWADroid is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SWADroid 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SWADroid. If not, see <http://www.gnu.org/licenses/>.
*/
package es.ugr.swad.swadroid.database;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import android.util.Log;
import com.android.dataframework.DataFramework;
import com.android.dataframework.Entity;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.model.Course;
import es.ugr.swad.swadroid.model.Event;
import es.ugr.swad.swadroid.model.FrequentUser;
import es.ugr.swad.swadroid.model.Group;
import es.ugr.swad.swadroid.model.GroupType;
import es.ugr.swad.swadroid.model.Model;
import es.ugr.swad.swadroid.model.Pair;
import es.ugr.swad.swadroid.model.PairTable;
import es.ugr.swad.swadroid.model.SWADNotification;
import es.ugr.swad.swadroid.model.Test;
import es.ugr.swad.swadroid.model.TestAnswer;
import es.ugr.swad.swadroid.model.TestQuestion;
import es.ugr.swad.swadroid.model.TestTag;
import es.ugr.swad.swadroid.model.User;
import es.ugr.swad.swadroid.model.UserAttendance;
import es.ugr.swad.swadroid.preferences.Preferences;
import es.ugr.swad.swadroid.utils.Crypto;
import es.ugr.swad.swadroid.utils.OldCrypto;
import es.ugr.swad.swadroid.utils.Utils;
/**
* Helper for database operations
*
* @author Juan Miguel Boyero Corral <juanmi1982@gmail.com>
* @author Antonio Aguilera Malagon <aguilerin@gmail.com>
* @author Helena Rodriguez Gijon <hrgijon@gmail.com>
*/
public class DataBaseHelper {
/**
* DataBaseHelper tag name for Logcat
*/
private static final String TAG = Constants.APP_TAG + " DataBaseHelper";
/**
* Field for access to the database backend
*/
private DataFramework db;
/**
* Application context
*/
private final Context mCtx;
/**
* Database passphrase
*/
private String DBKey;
/**
* Cryptographic object
*/
private final Crypto crypto;
/**
* Indicates if there are changes on db
*/
private static boolean dbCleaned = false;
/**
* Table name for courses
*/
public static final String DB_TABLE_COURSES = "courses";
/**
* Table name for notifications
*/
public static final String DB_TABLE_NOTIFICATIONS = "notifications";
/**
* Table name for test's answers
*/
public static final String DB_TABLE_TEST_ANSWERS = "tst_answers";
/**
* Table name for test's questions
*/
public static final String DB_TABLE_TEST_QUESTIONS = "tst_questions";
/**
* Table name for test's tags
*/
public static final String DB_TABLE_TEST_TAGS = "tst_tags";
/**
* Table name for test's configuration
*/
public static final String DB_TABLE_TEST_CONFIG = "tst_config";
/**
* Table name for relationship between test's questions and tags
*/
public static final String DB_TABLE_TEST_QUESTION_TAGS = "tst_question_tags";
/**
* Table name for relationship between test's questions and courses
*/
public static final String DB_TABLE_TEST_QUESTIONS_COURSE = "tst_questions_course";
/**
* Table name for relationship between test's questions and answers
*/
public static final String DB_TABLE_TEST_QUESTION_ANSWERS = "tst_question_answers";
/**
* Table name for users
*/
public static final String DB_TABLE_USERS = "users";
/**
* Table name for relationship between users and courses
*/
public static final String DB_TABLE_USERS_COURSES = "users_courses";
/**
* Table name for relationship between users and attendances
*/
public static final String DB_TABLE_USERS_ATTENDANCES = "users_attendances";
/**
* Table name for events
*/
public static final String DB_TABLE_EVENTS_ATTENDANCES = "events_attendances";
/**
* Table name for relationship between events and courses
*/
public static final String DB_TABLE_EVENTS_COURSES = "events_courses";
/**
* Table name for groups
*/
public static final String DB_TABLE_GROUPS = "groups";
/**
* Table name for relationship between groups and courses
*/
public static final String DB_TABLE_GROUPS_COURSES = "group_course";
/**
* Table name for group types
*/
public static final String DB_TABLE_GROUP_TYPES = "group_types";
/**
* Table name for relationship between groups and group types
*/
public static final String DB_TABLE_GROUPS_GROUPTYPES = "group_grouptypes";
/**
* Table name for practice sessions
*/
@Deprecated
public static final String DB_TABLE_PRACTICE_SESSIONS = "practice_sessions";
/**
* Table name for rollcall
*/
@Deprecated
public static final String DB_TABLE_ROLLCALL = "rollcall";
/**
* Table name for frequent recipients
*/
public static final String DB_TABLE_FREQUENT_RECIPIENTS = "frequent_recipients";
/**
* Constructor
* @throws IOException
* @throws XmlPullParserException
*/
public DataBaseHelper(Context ctx) throws XmlPullParserException, IOException {
mCtx = ctx;
DBKey = Preferences.getDBKey();
db = DataFramework.getInstance();
db.open(mCtx, mCtx.getPackageName());
//If the passphrase is empty, generate a random passphrase and recreate database
if (DBKey.equals("")) {
/*
Database passphrase length
*/
int DB_KEY_LENGTH = 128;
DBKey = Utils.randomString(DB_KEY_LENGTH);
Preferences.setDBKey(DBKey);
}
crypto = new Crypto(ctx, DBKey);
//Log.d("DataBaseHelper", "DBKey=" + DBKey);
}
/**
* Closes the database
*/
public synchronized void close() {
db.close();
}
/**
* Gets DB object
*
* @return DataFramework DB object
*/
public DataFramework getDb() {
return db;
}
/**
* Sets DB object
*
* @param db DataFramework DB object
*/
public void setDb(DataFramework db) {
this.db = db;
}
/**
* Gets the database encription key
* @return the database encription key
*/
public String getDBKey() {
return DBKey;
}
/**
* Selects the appropriated parameters for access a table
*
* @param table Table to be accessed
* @return A pair of strings containing the selected parameters
*/
private Pair<String, String> selectParamsPairTable(String table) {
String firstParam = null;
String secondParam = null;
switch (table) {
case DataBaseHelper.DB_TABLE_TEST_QUESTIONS_COURSE:
firstParam = "qstCod";
secondParam = "crsCod";
break;
case DataBaseHelper.DB_TABLE_TEST_QUESTION_ANSWERS:
firstParam = "qstCod";
secondParam = "ansCod";
break;
case DataBaseHelper.DB_TABLE_USERS_COURSES:
firstParam = "userCode";
secondParam = "crsCod";
break;
case DataBaseHelper.DB_TABLE_GROUPS_COURSES:
firstParam = "grpCod";
secondParam = "crsCod";
break;
case DataBaseHelper.DB_TABLE_GROUPS_GROUPTYPES:
firstParam = "grpTypCod";
secondParam = "grpCod";
break;
case DataBaseHelper.DB_TABLE_EVENTS_COURSES:
firstParam = "eventCode";
secondParam = "crsCod";
break;
default:
Log.e("selectParamsPairTable", "Table " + table + " not exists");
break;
}
return new Pair<>(firstParam, secondParam);
}
/**
* Gets ParTable class from table
* @param <T>
* */
/* private <T> PairTable<T, T> getPairTable(String table, T firstValue, T secondValue){
PairTable<T,T> par;
if(table.equals(Global.DB_TABLE_GROUPS_GROUPTYPES)){
par = new PairTable<T,T>(table,firstValue,secondValue);
}
return new Pair<Class,Class>(firstClass,secondClass);
}*/
/**
* Creates a Model's subclass object looking at the table selected
*
* @param table Table selected
* @param ent Cursor to the table rows
* @return A Model's subclass object
*/
private <T extends Model> T createObjectByTable(String table, Entity ent) {
Model o = null;
Pair<String, String> params;
long id;
switch (table) {
case DataBaseHelper.DB_TABLE_COURSES:
o = new Course(ent.getInt("id"),
ent.getInt("userRole"),
ent.getString("shortName"),
ent.getString("fullName"));
break;
case DataBaseHelper.DB_TABLE_TEST_QUESTIONS_COURSE:
case DataBaseHelper.DB_TABLE_TEST_QUESTION_ANSWERS:
case DataBaseHelper.DB_TABLE_USERS_COURSES:
case DataBaseHelper.DB_TABLE_GROUPS_COURSES:
case DataBaseHelper.DB_TABLE_GROUPS_GROUPTYPES:
case DataBaseHelper.DB_TABLE_EVENTS_COURSES:
params = selectParamsPairTable(table);
o = new PairTable<>(table,
ent.getInt(params.getFirst()),
ent.getInt(params.getSecond()));
break;
case DataBaseHelper.DB_TABLE_NOTIFICATIONS:
String nickName = ent.getString("userNickname");
String decryptedNickname = (nickName != null && !nickName.isEmpty())? crypto.decrypt(nickName) : "";
o = new SWADNotification(ent.getInt("notifCode"),
ent.getInt("eventCode"),
crypto.decrypt(ent.getString("eventType")),
ent.getLong("eventTime"),
decryptedNickname,
crypto.decrypt(ent.getString("userSurname1")),
crypto.decrypt(ent.getString("userSurname2")),
crypto.decrypt(ent.getString("userFirstname")),
crypto.decrypt(ent.getString("userPhoto")),
crypto.decrypt(ent.getString("location")),
crypto.decrypt(ent.getString("summary")),
ent.getInt("status"),
crypto.decrypt(ent.getString("content")),
Utils.parseStringBool(ent.getString("seenLocal")),
Utils.parseStringBool(ent.getString("seenRemote")));
break;
case DataBaseHelper.DB_TABLE_TEST_QUESTIONS:
id = ent.getInt("id");
PairTable<?, ?> q = getRow(DataBaseHelper.DB_TABLE_TEST_QUESTIONS_COURSE, "qstCod", Long.toString(id));
if (q != null) {
o = new TestQuestion(id,
(Integer) q.getFirst(),
ent.getString("stem"),
ent.getString("ansType"),
Utils.parseStringBool(ent.getString("shuffle")),
ent.getString("feedback"));
} else {
o = null;
}
break;
case DataBaseHelper.DB_TABLE_TEST_ANSWERS:
id = ent.getId();
int ansInd = ent.getInt("ansInd");
PairTable<?, ?> a = getRow(DataBaseHelper.DB_TABLE_TEST_QUESTION_ANSWERS, "ansCod", Long.toString(id));
if (a != null) {
o = new TestAnswer(id,
ansInd,
(Integer) a.getFirst(),
Utils.parseStringBool(ent.getString("correct")),
ent.getString("answer"),
ent.getString("answerFeedback"));
} else {
o = null;
}
break;
case DataBaseHelper.DB_TABLE_TEST_TAGS:
id = ent.getInt("tagCod");
TestTag t = getRow(DataBaseHelper.DB_TABLE_TEST_QUESTION_TAGS, "tagCod", Long.toString(id));
if (t != null) {
o = new TestTag(id,
t.getQstCodList(),
ent.getString("tagTxt"),
ent.getInt("tagInd"));
} else {
o = null;
}
break;
case DataBaseHelper.DB_TABLE_TEST_CONFIG:
o = new Test(ent.getInt("id"),
ent.getInt("min"),
ent.getInt("def"),
ent.getInt("max"),
ent.getString("feedback"),
ent.getLong("editTime"));
break;
case DataBaseHelper.DB_TABLE_TEST_QUESTION_TAGS:
ArrayList<Integer> l = new ArrayList<>();
l.add(ent.getInt("qstCod"));
o = new TestTag(ent.getInt("tagCod"),
l,
null,
ent.getInt("tagInd"));
break;
case DataBaseHelper.DB_TABLE_USERS:
try {
o = new User(ent.getInt("userCode"),
null, // wsKey
ent.getString("userID"),
ent.getString("userNickname"),
ent.getString("userSurname1"),
ent.getString("userSurname2"),
ent.getString("userFirstname"),
ent.getString("photoPath"),
null, //userBirthday
ent.getInt("userRole"));
} catch (ParseException e) {
Log.e(TAG, e.getMessage(), e);
}
break;
case DataBaseHelper.DB_TABLE_USERS_ATTENDANCES:
o = new UserAttendance(ent.getInt("userCode"),
ent.getInt("eventCode"),
Utils.parseIntBool(ent.getInt("present")));
break;
case DataBaseHelper.DB_TABLE_EVENTS_ATTENDANCES:
o = new Event(ent.getLong("id"),
Utils.parseIntBool(ent.getInt("hidden")),
crypto.decrypt(ent.getString("userSurname1")),
crypto.decrypt(ent.getString("userSurname2")),
crypto.decrypt(ent.getString("userFirstName")),
crypto.decrypt(ent.getString("userPhoto")),
ent.getLong("startTime"),
ent.getLong("endTime"),
Utils.parseIntBool(ent.getInt("commentsTeachersVisible")),
crypto.decrypt(ent.getString("title")),
crypto.decrypt(ent.getString("text")),
crypto.decrypt(ent.getString("groups")),
crypto.decrypt(ent.getString("status")));
break;
case DataBaseHelper.DB_TABLE_GROUPS:
long groupTypeCode = getGroupTypeCodeFromGroup(ent.getLong("id"));
o = new Group(ent.getLong("id"),
ent.getString("groupName"),
groupTypeCode,
ent.getInt("maxStudents"),
ent.getInt("open"),
ent.getInt("students"),
ent.getInt("fileZones"),
ent.getInt("member"));
break;
case DataBaseHelper.DB_TABLE_GROUP_TYPES:
o = new GroupType(ent.getLong("id"),
ent.getString("groupTypeName"),
ent.getLong("courseCode"),
ent.getInt("mandatory"),
ent.getInt("multiple"),
ent.getLong("openTime"));
break;
case DataBaseHelper.DB_TABLE_FREQUENT_RECIPIENTS:
o = new FrequentUser(ent.getString("idUser"),
crypto.decrypt(ent.getString("nicknameRecipient")),
crypto.decrypt(ent.getString("surname1Recipient")),
crypto.decrypt(ent.getString("surname2Recipient")),
crypto.decrypt(ent.getString("firstnameRecipient")),
crypto.decrypt(ent.getString("photoRecipient")),
ent.getInt("userCode"),
false,
ent.getDouble("score"));
break;
}
return (T) o;
}
/**
* Gets all rows of specified table
*
* @param table Table containing the rows
* @return A list of Model's subclass objects
*/
public <T extends Model> List<T> getAllRows(String table) {
List<T> result = new ArrayList<>();
List<Entity> rows = db.getEntityList(table);
T row;
for (Entity ent : rows) {
row = createObjectByTable(table, ent);
result.add(row);
}
return result;
}
/**
* Gets the rows of specified table that matches "where" condition. The rows are ordered as says the "orderby"
* parameter
*
* @param table Table containing the rows
* @param where Where condition of SQL sentence
* @param orderby Orderby part of SQL sentence
* @return A list of Model's subclass objects
*/
public <T extends Model> List<T> getAllRows(String table, String where, String orderby) {
List<T> result = new ArrayList<>();
List<Entity> rows = db.getEntityList(table, where, orderby);
T row;
if (rows != null) {
for (Entity ent : rows) {
row = createObjectByTable(table, ent);
result.add(row);
}
}
return result;
}
/**
* Gets count of all rows of specified table
*
* @param table Table containing the rows
* @return Count of all rows of specified table
*/
public int getAllRowsCount(String table) {
return db.getEntityListCount(table, null);
}
/**
* Gets count of all rows of specified table
*
* @param table Table containing the rows
* @param where Where condition of SQL sentence
* @return Count of all rows of specified table
*/
public int getAllRowsCount(String table, String where) {
return db.getEntityListCount(table, where);
}
/**
* Gets a row of specified table
*
* @param table Table containing the rows
* @param fieldName Field's name
* @param fieldValue Field's value
* @return A Model's subclass object
* or null if the row does not exist in the specified table
*/
public <T extends Model> T getRow(String table, String fieldName, Object fieldValue) {
List<Entity> rows;
Entity ent;
T row = null;
if(fieldValue instanceof String) {
rows = db.getEntityList(table, fieldName + " = '" + fieldValue + "'");
} else {
rows = db.getEntityList(table, fieldName + " = " + fieldValue + "");
}
if (rows.size() > 0) {
ent = rows.get(0);
row = createObjectByTable(table, ent);
}
return row;
}
/**
* Gets all tablenames of the database
*
* @return A list of all tablenames of the database
*/
public List<String> getAllTablenames() {
List<String> result = new ArrayList<>();
Cursor cursor = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name", null);
while (cursor.moveToNext()) {
result.add(cursor.getString(0));
}
return result;
}
/**
* Gets an user
*
* @param fieldName Field's name
* @param fieldValue Field's value
* @return The user found
* or null if the user does not exist
*/
public User getUser(String fieldName, Object fieldValue) {
List<Entity> rows;
Entity ent;
User user = null;
if(fieldValue instanceof String) {
rows = db.getEntityList(DataBaseHelper.DB_TABLE_USERS, fieldName + " = '" + fieldValue + "'");
} else {
rows = db.getEntityList(DataBaseHelper.DB_TABLE_USERS, fieldName + " = " + fieldValue + "");
}
if (rows.size() > 0) {
ent = rows.get(0);
try {
user = new User(
ent.getLong("userCode"),
null,
crypto.decrypt(ent.getString("userID")),
crypto.decrypt(ent.getString("userNickname")),
crypto.decrypt(ent.getString("userSurname1")),
crypto.decrypt(ent.getString("userSurname2")),
crypto.decrypt(ent.getString("userFirstname")),
crypto.decrypt(ent.getString("photoPath")),
null,
ent.getInt("userRole"));
} catch (ParseException e) {
Log.e(TAG, e.getMessage(), e);
}
}
return user;
}
/**
* Gets the id of users enrolled in the selected course
*
* @param courseCode Course code to be referenced
* @return A list of User's id
*/
public List<Long> getUsersCourse(long courseCode) {
List<Long> result = new ArrayList<>();
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_USERS_COURSES, "crsCod = '" + courseCode + "'");
if (rows != null) {
for (Entity ent : rows) {
result.add(ent.getLong("userCode"));
}
}
return result;
}
/**
* Gets the id of users related to the selected event
*
* @param eventCode Event code to be referenced
* @return A list of User's id
*/
public List<Long> getUserIdsEvent(int eventCode) {
List<Long> result = new ArrayList<>();
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_USERS_ATTENDANCES, "eventCode = '" + eventCode + "'");
if (rows != null) {
for (Entity ent : rows) {
result.add(ent.getLong("userCode"));
}
}
return result;
}
/**
* Gets the list of users related to the selected event
*
* @param eventCode Event code to be referenced
* @return A list of @link{UserAttendance} related to the selected event
*/
public List<UserAttendance> getUsersEvent(int eventCode) {
List<UserAttendance> result = new ArrayList<>();
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_USERS_ATTENDANCES, "eventCode = '" + eventCode + "'");
if (rows != null) {
for (Entity ent : rows) {
result.add( (UserAttendance) createObjectByTable(DataBaseHelper.DB_TABLE_USERS_ATTENDANCES, ent));
}
}
return result;
}
/**
* Checks if the user is enrolled in the selected event
*
* @param eventCode Event code to be referenced
* @param fieldName Field's name
* @param fieldValue Field's value
* @return true if the user is enrolled in the selected event
* false if the user is not enrolled in the selected event
*/
public boolean isUserEnrolledEvent(int eventCode, String fieldName, String fieldValue) {
return (getAllRowsCount(DB_TABLE_USERS_ATTENDANCES, "eventCode = '" + eventCode + "'" +
" AND " + fieldName + " = '" + fieldValue + "'") != 0);
}
/**
* Gets the list of users related to the selected event
*
* @param eventCode Event code to be referenced
* @return A Cursor with a list of users related to the selected event
*/
public Cursor getUsersEventCursor(int eventCode) {
return db.rawQuery("SELECT * FROM " + DB_TABLE_USERS + " AS U"
+ " INNER JOIN " + DB_TABLE_USERS_ATTENDANCES + " AS A"
+ " ON U.userCode = A.userCode WHERE eventCode ='" + eventCode + "'", null);
}
/**
* Gets the list of events related to the selected course
*
* @param crsCod Course code to be referenced
* @return A list of Event
*/
public List<Event> getEventsCourse(long crsCod) {
List<Event> result = new ArrayList<>();
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_EVENTS_COURSES, "crsCod = '" + crsCod + "'");
if (rows != null) {
for (Entity ent : rows) {
result.add((Event) getRow(DataBaseHelper.DB_TABLE_EVENTS_ATTENDANCES, "id", ent.getValue("eventCode")));
}
}
return result;
}
/**
* Gets the list of users related to the selected event
*
* @param crsCod Course code to be referenced
* @return A Cursor with a list of events related to the selected course
*/
public Cursor getEventsCourseCursor(long crsCod) {
return db.rawQuery("SELECT * FROM " + DB_TABLE_EVENTS_ATTENDANCES + " AS E"
+ " INNER JOIN " + DB_TABLE_EVENTS_COURSES + " AS C"
+ " ON E.id = C.eventCode WHERE C.crsCod ='" + crsCod + "' AND hidden=" + Utils.parseBoolInt(false)
+ " ORDER BY E.startTime DESC,E.endTime DESC,E.title DESC", null);
}
/**
* Gets the number of users related to the selected event
*
* @param eventCode Event code to be referenced
* @return the number of users related to the selected event
*/
public int getUsersEventCount(int eventCode) {
Cursor cursor = db.rawQuery("SELECT COUNT(*) AS COUNT FROM " + DB_TABLE_USERS + " AS U"
+ " INNER JOIN " + DB_TABLE_USERS_ATTENDANCES + " AS A"
+ " ON U.userCode = A.userCode WHERE eventCode = '" + eventCode + "'", null);
return cursor.getInt(cursor.getColumnIndex("COUNT"));
}
/**
* Gets the number of users related to the selected event
*
* @param eventCode Event code to be referenced
* @param fieldName Field's name
* @param fieldValue Field's value
* @return the number of users related to the selected event
*/
public int getUsersEventCount(int eventCode, String fieldName, String fieldValue) {
Cursor cursor = db.rawQuery("SELECT COUNT(*) AS COUNT FROM " + DB_TABLE_USERS + " AS U"
+ " INNER JOIN " + DB_TABLE_USERS_ATTENDANCES + " AS A"
+ " ON U.userCode = A.userCode WHERE eventCode = '" + eventCode + "'" +
" AND " + fieldName + " = '" + fieldValue + "'", null);
return cursor.getInt(cursor.getColumnIndex("COUNT"));
}
/**
* Gets the group which code is given
*
* @param groupId long that identifies uniquely the searched group
* @return group with the referenced code in case it exits
* null otherwise
*/
public Group getGroup(long groupId) {
String table = DataBaseHelper.DB_TABLE_GROUPS;
List<Entity> rows = db.getEntityList(table, "id = " + groupId);
Group g = null;
if (rows != null)
g = createObjectByTable(table, rows.get(0));
return g;
}
/**
* Gets the group codes in the selected course
*
* @param courseCode Course code to be referenced
* @return A list of group codes belonging to the selected course
*/
public List<Long> getGroupCodesCourse(long courseCode) {
List<Long> result = new ArrayList<>();
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_GROUPS_COURSES, "crsCod = '" + courseCode + "'");
if (rows != null) {
for (Entity ent : rows) {
result.add(ent.getLong("grpCod"));
}
}
return result;
}
/**
* Gets the groups belonging to the selected type of group
*
* @param groupTypeCode group type code to be referenced
* @return List of Groups
*/
public List<Group> getGroupsOfType(long groupTypeCode) {
List<Group> groups = new ArrayList<>();
List<Long> groupCodes = getGroupsCodesOfType(groupTypeCode);
if (!groupCodes.isEmpty()) {
for (Long groupCode : groupCodes) {
groups.add((Group) getRow(DataBaseHelper.DB_TABLE_GROUPS, "id", String.valueOf(groupCode)));
}
}
return groups;
}
public Cursor getCursor(String table) {
return db.getCursor(table);
}
public Cursor getCursor(String table, String where, String orderby) {
return db.getCursor(table, where, orderby);
}
public Cursor getCursorGroupType(long courseCode) {
return db.getCursor(DataBaseHelper.DB_TABLE_GROUP_TYPES, "courseCode =" + courseCode, "groupTypeName");
}
public GroupType getGroupTypeFromGroup(long groupCode) {
long groupTypeCode = getGroupTypeCodeFromGroup(groupCode);
return (GroupType) getRow(DataBaseHelper.DB_TABLE_GROUP_TYPES, "id", String.valueOf(groupTypeCode));
}
/**
* Gets the code of the group type belonging the group with the given group code
*
* @param groupCode long that specifies the code of the group
* @return group type code in case the given group belongs to a group type
* -1 otherwise
*/
long getGroupTypeCodeFromGroup(long groupCode) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_GROUPS_GROUPTYPES, "grpCod = '" + groupCode + "'");
long groupTypeCode = -1;
if (!rows.isEmpty()) {
groupTypeCode = rows.get(0).getLong("grpTypCod");
}
return groupTypeCode;
}
/**
* Gets the codes of groups belonging the selected type of group
*
* @param groupTypeCode group type code to be referenced
* @return List of group codes
*/
private List<Long> getGroupsCodesOfType(long groupTypeCode) {
List<Long> groupCodes = new ArrayList<>();
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_GROUPS_GROUPTYPES, "grpTypCod = '" + groupTypeCode + "'");
if (rows != null) {
for (Entity row : rows) {
groupCodes.add(row.getLong("grpCod"));
}
}
return groupCodes;
}
/**
* Get groups belonging to the referred course to which the logged user is enrolled
*
* @param courseCode course code to which the groups belong
* @return List of the group
*/
public List<Group> getUserLoggedGroups(long courseCode) {
List<Long> groupCodes = getGroupCodesCourse(courseCode);
List<Group> groups = new ArrayList<>();
if (!groupCodes.isEmpty()) {
for (Long groupCode : groupCodes) {
Group g = getRow(DataBaseHelper.DB_TABLE_GROUPS, "id", String.valueOf(groupCode));
if (g.isMember()) groups.add(g);
}
}
return groups;
}
/**
* Gets the practice groups in the selected course
*
* @param courseCode Course code to be referenced
* @return Cursor access to the practice groups
*/
public Cursor getPracticeGroups(long courseCode) {
String select = "SELECT " +
"g._id, g.id, gt.groupTypeName, g.groupName" +
" FROM " +
DataBaseHelper.DB_TABLE_GROUPS + " g, " + DataBaseHelper.DB_TABLE_GROUPS_COURSES + " gc, " +
DataBaseHelper.DB_TABLE_GROUP_TYPES + " gt, " + DataBaseHelper.DB_TABLE_GROUPS_GROUPTYPES + " ggt" +
" WHERE " +
"gc.crsCod = ? AND gc.grpCod = g.id AND gc.grpCod = ggt.grpCod AND ggt.grpTypCod = gt.id";
SQLiteDatabase db = DataFramework.getInstance().getDB();
return db.rawQuery(select, new String[]{String.valueOf(courseCode)});
}
/**
* Checks if the specified user is enrolled in the selected course
*
* @param selectedCourseCode Course code to be referenced
* @return True if user is enrolled in the selected course. False otherwise
*/
public boolean isUserEnrolledCourse(String userID, long selectedCourseCode) {
boolean enrolled = false;
User u = getRow(DataBaseHelper.DB_TABLE_USERS, "userID", userID);
if (u != null) {
String sentencia = "SELECT userCode AS _id, crsCod" +
" FROM " + DataBaseHelper.DB_TABLE_USERS_COURSES +
" WHERE userCode = ? AND crsCod = ?" +
" ORDER BY 1";
Cursor c = db.getDB().rawQuery(sentencia, new String[]{
String.valueOf(u.getId()),
String.valueOf(selectedCourseCode)
});
if (c.moveToFirst()) {
enrolled = true;
}
c.close();
} else
enrolled = false;
return enrolled;
}
/**
* Gets the groups that owns the selected course
*
* @param courseCode Course code to be referenced
* @return Cursor access to the groups
*/
public List<Group> getGroups(long courseCode) {
String select = "SELECT grpCod FROM " + DataBaseHelper.DB_TABLE_GROUPS_COURSES + " WHERE crsCod = " + courseCode + ";";
Cursor groupCodes = db.getDB().rawQuery(select, null);
List<Group> groups = new ArrayList<>(groupCodes.getCount());
while (groupCodes.moveToNext()) {
Group group = this.getRow(DataBaseHelper.DB_TABLE_GROUPS, "id", String.valueOf(groupCodes.getInt(0)));
groups.add(group);
}
groupCodes.close();
return groups;
}
/**
* Inserts a course in database
*
* @param c Course to be inserted
*/
public void insertCourse(Course c) {
Entity ent = new Entity(DataBaseHelper.DB_TABLE_COURSES);
ent.setValue("id", c.getId());
ent.setValue("userRole", c.getUserRole());
ent.setValue("shortName", c.getShortName());
ent.setValue("fullName", c.getFullName());
ent.save();
}
/**
* Inserts a notification in database
*
* @param n Notification to be inserted
*/
public void insertNotification(SWADNotification n) {
Entity ent = new Entity(DataBaseHelper.DB_TABLE_NOTIFICATIONS);
String eventTime = String.valueOf(n.getEventTime());
String status = String.valueOf(n.getStatus());
ent.setValue("notifCode", n.getId());
ent.setValue("eventCode", n.getEventCode());
ent.setValue("eventType", crypto.encrypt(n.getEventType()));
ent.setValue("eventTime", eventTime);
ent.setValue("userNickname", crypto.encrypt(n.getUserNickname()));
ent.setValue("userSurname1", crypto.encrypt(n.getUserSurname1()));
ent.setValue("userSurname2", crypto.encrypt(n.getUserSurname2()));
ent.setValue("userFirstname", crypto.encrypt(n.getUserFirstName()));
ent.setValue("userPhoto", crypto.encrypt(n.getUserPhoto()));
ent.setValue("location", crypto.encrypt(n.getLocation()));
ent.setValue("summary", crypto.encrypt(n.getSummary()));
ent.setValue("status", status);
ent.setValue("content", crypto.encrypt(n.getContent()));
ent.setValue("seenLocal", Utils.parseBoolString(n.isSeenLocal()));
ent.setValue("seenRemote", Utils.parseBoolString(n.isSeenRemote()));
ent.save();
}
/**
* Inserts a test question in database
*
* @param q Test question to be inserted
* @param selectedCourseCode Course code to be referenced
*/
public void insertTestQuestion(TestQuestion q, long selectedCourseCode) {
Entity ent = new Entity(DataBaseHelper.DB_TABLE_TEST_QUESTIONS);
ent.setValue("id", q.getId());
ent.setValue("ansType", q.getAnswerType());
ent.setValue("stem", q.getStem());
ent.setValue("shuffle", Utils.parseBoolString(q.getShuffle()));
ent.setValue("feedback", q.getFeedback());
ent.save();
ent = new Entity(DataBaseHelper.DB_TABLE_TEST_QUESTIONS_COURSE);
ent.setValue("qstCod", q.getId());
ent.setValue("crsCod", selectedCourseCode);
ent.save();
}
/**
* Inserts a test answer in database
*
* @param a Test answer to be inserted
* @param qstCod Test question code to be referenced
*/
public void insertTestAnswer(TestAnswer a, int qstCod) {
Entity ent = new Entity(DataBaseHelper.DB_TABLE_TEST_ANSWERS);
long id;
ent.setValue("ansInd", a.getAnsInd());
ent.setValue("answer", a.getAnswer());
ent.setValue("correct", a.getCorrect());
ent.setValue("answerFeedback", a.getFeedback());
ent.save();
id = ent.getId();
ent = new Entity(DataBaseHelper.DB_TABLE_TEST_QUESTION_ANSWERS);
ent.setValue("qstCod", qstCod);
ent.setValue("ansCod", id);
ent.save();
}
/**
* Inserts a test tag in database
*
* @param t Test tag to be inserted
*/
public void insertTestTag(TestTag t) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_TEST_TAGS, "id = " + t.getId());
if (rows.isEmpty()) {
Entity ent = new Entity(DataBaseHelper.DB_TABLE_TEST_TAGS);
ent.setValue("id", t.getId());
ent.setValue("tagTxt", t.getTagTxt());
ent.save();
for (Integer i : t.getQstCodList()) {
ent = new Entity(DataBaseHelper.DB_TABLE_TEST_QUESTION_TAGS);
ent.setValue("qstCod", i);
ent.setValue("tagCod", t.getId());
ent.setValue("tagInd", t.getTagInd());
ent.save();
}
} else {
throw new SQLException("Duplicated tag");
}
}
/**
* Inserts a test config in database
*
* @param t Test config to be inserted
*/
public void insertTestConfig(Test t) {
Entity ent = new Entity(DataBaseHelper.DB_TABLE_TEST_CONFIG);
ent.setValue("id", t.getId());
ent.setValue("min", t.getMin());
ent.setValue("def", t.getDef());
ent.setValue("max", t.getMax());
ent.setValue("feedback", t.getFeedback());
ent.setValue("editTime", t.getEditTime());
ent.save();
}
/**
* Inserts a relation in database
*
* @param p Relation to be inserted
*/
void insertPairTable(PairTable<?, ?> p) {
String table = p.getTable();
Pair<String, String> params = selectParamsPairTable(table);
Entity ent = new Entity(table);
ent.setValue(params.getFirst(), p.getFirst());
ent.setValue(params.getSecond(), p.getSecond());
ent.save();
}
/**
* Inserts a new row or updates an existing one in the table named @a tableName with the data that contains @a currentModel
*
* @param tableName string with the table name
* @param currentModel model with the new data
* @param ents vector of entities. In case this param is given, the entities given will be modified
*/
boolean insertEntity(String tableName, Model currentModel, Entity... ents) {
boolean returnValue = true;
Entity ent;
if (ents.length >= 1) {
ent = ents[0];
} else {
ent = new Entity(tableName);
}
if (tableName.equals(DataBaseHelper.DB_TABLE_GROUPS)) {
Group g = (Group) currentModel;
ent.setValue("id", g.getId());
ent.setValue("groupName", g.getGroupName());
ent.setValue("maxStudents", g.getMaxStudents());
ent.setValue("students", g.getCurrentStudents());
ent.setValue("open", g.getOpen());
ent.setValue("fileZones", g.getDocumentsArea());
ent.setValue("member", g.getMember());
ent.save();
}
if (tableName.equals(DataBaseHelper.DB_TABLE_GROUP_TYPES)) {
GroupType gt = (GroupType) currentModel;
ent.setValue("id", gt.getId());
ent.setValue("groupTypeName", gt.getGroupTypeName());
ent.setValue("courseCode", gt.getCourseCode());
ent.setValue("mandatory", gt.getMandatory());
ent.setValue("multiple", gt.getMultiple());
ent.setValue("openTime", gt.getOpenTime());
ent.save();
}
return returnValue;
}
/**
* Inserts a user in database or updates it if already exists
*
* @param u User to be inserted
*/
public void insertUser(User u) {
Entity ent;
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_USERS, "userCode = " + u.getId());
if (rows.isEmpty()) {
ent = new Entity(DataBaseHelper.DB_TABLE_USERS);
} else {
ent = rows.get(0);
}
ent.setValue("userCode", u.getId());
ent.setValue("userID", crypto.encrypt(u.getUserID()));
ent.setValue("userNickname", crypto.encrypt(u.getUserNickname()));
ent.setValue("userSurname1", crypto.encrypt(u.getUserSurname1()));
ent.setValue("userSurname2", crypto.encrypt(u.getUserSurname2()));
ent.setValue("userFirstname", crypto.encrypt(u.getUserFirstname()));
if(u.getUserPhoto() != null) {
ent.setValue("photoPath", crypto.encrypt(u.getUserPhoto()));
} else {
ent.setValue("photoPath", null);
}
ent.setValue("userRole", u.getUserRole());
ent.save();
}
/**
* Inserts a group in database
*
* @param g Group to be inserted
* @param courseCode Course code to be referenced
*/
public boolean insertGroup(Group g, long courseCode) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_GROUPS, "id = " + g.getId());
boolean returnValue = true;
if (rows.isEmpty()) {
insertEntity(DataBaseHelper.DB_TABLE_GROUPS, g);
} else { //already exits a group with the given code. just update
insertEntity(DataBaseHelper.DB_TABLE_GROUPS, g, rows.get(0));
}
//update all the relationship
long groupCode = g.getId();
rows = db.getEntityList(DataBaseHelper.DB_TABLE_GROUPS_COURSES, "grpCod =" + groupCode);
Course course = getRow(DataBaseHelper.DB_TABLE_COURSES, "id", String.valueOf(courseCode));
//course code is a foreign key. Therefore, to avoid a database error,
//it should not insert/modify rows in the relationship table if the course does not exists
if (course != null) {
if (rows.isEmpty()) {
PairTable<Long, Long> pair = new PairTable<>(DataBaseHelper.DB_TABLE_GROUPS_COURSES, g.getId(), courseCode);
insertPairTable(pair);
} else {
rows.get(0).setValue("crsCod", courseCode);
rows.get(0).save();
}
} else returnValue = false;
long groupTypeCode = g.getGroupTypeCode();
//WHILE THE WEB SERVICE TO GET GROUP TYPES STILL UNAVAILABLE, this condition is not evaluated
//GroupType groupType = (GroupType) getRow(Global.DB_TABLE_GROUP_TYPES,"id",String.valueOf(groupTypeCode));
//group type code is a foreign key. Therefore, to avoid a database error,
//it should not insert/modify rows in the relationship table if the group type does not exists
//if(groupType != null){
rows = db.getEntityList(DataBaseHelper.DB_TABLE_GROUPS_GROUPTYPES, "grpCod=" + groupCode);
if (rows.isEmpty()) {
insertPairTable(new PairTable<>(DataBaseHelper.DB_TABLE_GROUPS_GROUPTYPES, groupTypeCode, groupCode));
} else {
PairTable<Object, Object> prev = new PairTable<>(DataBaseHelper.DB_TABLE_GROUPS_GROUPTYPES, rows.get(0).getValue("grpTypCod"), rows.get(0).getValue("grpCod"));
PairTable<Object, Object> current = new PairTable<Object, Object>(DataBaseHelper.DB_TABLE_GROUPS_GROUPTYPES, groupTypeCode, groupCode);
updatePairTable(prev, current);
}
/*}else returnValue = false;*/
return returnValue;
}
/**
* Insert a new group type in the database or updated if the group type exits already in the data base
*
* @param gt Group Type to be inserted
*/
public boolean insertGroupType(GroupType gt) {
boolean returnValue = true;
GroupType row = getRow(DataBaseHelper.DB_TABLE_GROUP_TYPES, "id", String.valueOf(gt.getId()));
if (row == null) {
insertEntity(DataBaseHelper.DB_TABLE_GROUP_TYPES, gt);
} else {
returnValue = false;
}
return returnValue;
}
public boolean insertCollection(String table, List<Model> currentModels, long... courseCode) {
boolean result = true;
Collection<? extends Model> modelsDB = getAllRows(table);
List<Model> newModels = new ArrayList<>();
List<Model> obsoleteModel = new ArrayList<>();
List<Model> modifiedModel = new ArrayList<>();
beginTransaction();
newModels.addAll(currentModels);
newModels.removeAll(modelsDB);
obsoleteModel.addAll(modelsDB);
obsoleteModel.removeAll(currentModels);
modifiedModel.addAll(currentModels);
modifiedModel.removeAll(newModels);
modifiedModel.removeAll(obsoleteModel);
if (table.compareTo(DataBaseHelper.DB_TABLE_GROUP_TYPES) == 0) {
for (Model anObsoleteModel : obsoleteModel) {
long code = anObsoleteModel.getId();
removeAllRows(table, "id", code);
removeAllRows(DataBaseHelper.DB_TABLE_GROUPS_GROUPTYPES, "grpTypCod", code);
}
for (Model model : newModels) {
insertEntity(table, model);
}
List<Entity> rows;
for (Model m : modifiedModel) {
rows = db.getEntityList(table, "id=" + m.getId());
insertEntity(table, m, rows.get(0));
}
}
if (table.compareTo(DataBaseHelper.DB_TABLE_GROUPS) == 0) {
for (Model anObsoleteModel : obsoleteModel) {
long code = anObsoleteModel.getId();
removeAllRows(table, "id", code);
removeAllRows(DataBaseHelper.DB_TABLE_GROUPS_GROUPTYPES, "grpCod", code);
removeAllRows(DataBaseHelper.DB_TABLE_GROUPS_COURSES, "grpCod", code);
}
for (Model model : newModels) {
insertGroup((Group) model, courseCode[0]);
}
for (Model model : modifiedModel) {
insertGroup((Group) model, courseCode[0]);
}
}
//Finish the pending transaction with successful status
endTransaction(true);
return result;
}
/**
* Inserts a new record in database indicating that the user belongs
* to the course and group specified, or updates it if already exists
*
* @param userID User to be inserted
* @param courseCode Course code to be referenced
* @param groupCode Group code to be referenced
*/
public void insertUserCourse(long userID, long courseCode, long groupCode) {
Entity ent;
String where = "userCode = " + userID + " AND crsCod = " + courseCode;
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_USERS_COURSES, where);
if (rows.isEmpty()) {
ent = new Entity(DataBaseHelper.DB_TABLE_USERS_COURSES);
} else {
ent = rows.get(0);
}
ent.setValue("userCode", userID);
ent.setValue("crsCod", courseCode);
ent.setValue("grpCod", groupCode);
ent.save();
}
/**
* Inserts a new record in database indicating if the user has an
* attendance to the event specified, or updates it if already exists
*
* @param userCode User code to be inserted
* @param eventCode Event code to be referenced
* @param present Flag for indicate if the user is present in the attendance
*/
public void insertAttendance(long userCode, long eventCode, boolean present) {
Entity ent;
String where = "userCode = " + userCode + " AND eventCode = " + eventCode;
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_USERS_ATTENDANCES, where);
if (rows.isEmpty()) {
ent = new Entity(DataBaseHelper.DB_TABLE_USERS_ATTENDANCES);
} else {
ent = rows.get(0);
}
ent.setValue("userCode", userCode);
ent.setValue("eventCode", eventCode);
ent.setValue("present", Utils.parseBoolInt(present));
ent.save();
}
/**
* Inserts a new record in database for an attendance event,
* or updates it if already exists
*
* @param event Event to be inserted
*/
public void insertEvent(Event event) {
Entity ent;
String where = "id = " + event.getId();
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_EVENTS_ATTENDANCES, where);
if (rows.isEmpty()) {
ent = new Entity(DataBaseHelper.DB_TABLE_EVENTS_ATTENDANCES);
ent.setValue("status", crypto.encrypt(event.getStatus()));
} else {
ent = rows.get(0);
}
ent.setValue("id", event.getId());
ent.setValue("hidden", Utils.parseBoolInt(event.isHidden()));
ent.setValue("userSurname1", crypto.encrypt(event.getUserSurname1()));
ent.setValue("userSurname2", crypto.encrypt(event.getUserSurname2()));
ent.setValue("userFirstName", crypto.encrypt(event.getUserFirstName()));
ent.setValue("userPhoto", crypto.encrypt(event.getUserPhoto()));
ent.setValue("startTime", event.getStartTime());
ent.setValue("endTime", event.getEndTime());
ent.setValue("commentsTeachersVisible", Utils.parseBoolInt(event.isCommentsTeachersVisible()));
ent.setValue("title", crypto.encrypt(event.getTitle()));
ent.setValue("text", crypto.encrypt(event.getText()));
ent.setValue("groups", crypto.encrypt(event.getGroups()));
ent.save();
}
/**
* Inserts a new record in database for the relationship between an attendance event and a course,
* or updates it if already exists
*
* @param eventCode Event code
* @param crsCod Course code
*/
public void insertEventCourse(long eventCode, long crsCod) {
Entity ent;
String where = "eventCode = " + eventCode + " AND crsCod = " + crsCod;
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_EVENTS_COURSES, where);
if (rows.isEmpty()) {
ent = new Entity(DataBaseHelper.DB_TABLE_EVENTS_COURSES);
} else {
ent = rows.get(0);
}
ent.setValue("eventCode", eventCode);
ent.setValue("crsCod", crsCod);
ent.save();
}
/**
* Inserts a new Frequent Recipient
*
* @param user the frequent recipient to insert in the list
*/
public void insertFrequentRecipient(FrequentUser user) {
Entity ent = new Entity(DataBaseHelper.DB_TABLE_FREQUENT_RECIPIENTS);
ent.setValue("idUser", user.getidUser());
ent.setValue("nicknameRecipient", crypto.encrypt(user.getUserNickname()));
ent.setValue("surname1Recipient", crypto.encrypt(user.getUserSurname1()));
ent.setValue("surname2Recipient", crypto.encrypt(user.getUserSurname2()));
ent.setValue("firstnameRecipient", crypto.encrypt(user.getUserFirstname()));
ent.setValue("photoRecipient", crypto.encrypt(user.getUserPhoto()));
ent.setValue("score", user.getScore());
ent.save();
}
/**
* Inserts a list of frequent recipients
*
* @param list the list of users
* @return number of users inserted in the table
*/
public int insertFrequentsList(List<FrequentUser> list) {
int numElements = 0;
for(int i=0; i<list.size(); i++){
FrequentUser user = list.get(i);
Entity ent = new Entity(DataBaseHelper.DB_TABLE_FREQUENT_RECIPIENTS);
ent.setValue("idUser", user.getidUser());
ent.setValue("nicknameRecipient", crypto.encrypt(user.getUserNickname()));
ent.setValue("surname1Recipient", crypto.encrypt(user.getUserSurname1()));
ent.setValue("surname2Recipient", crypto.encrypt(user.getUserSurname2()));
ent.setValue("firstnameRecipient", crypto.encrypt(user.getUserFirstname()));
ent.setValue("photoRecipient", crypto.encrypt(user.getUserPhoto()));
ent.setValue("score", user.getScore());
ent.save();
numElements++;
}
return numElements;
}
/**
* Updates a course in database
*
* @param prev Course to be updated
* @param actual Updated course
*/
public void updateCourse(Course prev, Course actual) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_COURSES, "id = " + prev.getId());
Entity ent = rows.get(0);
ent.setValue("id", actual.getId());
ent.setValue("userRole", actual.getUserRole());
ent.setValue("shortName", actual.getShortName());
ent.setValue("fullName", actual.getFullName());
ent.save();
}
/**
* Updates a course in database
*
* @param id Course code of course to be updated
* @param actual Updated course
*/
public void updateCourse(long id, Course actual) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_COURSES, "id = " + id);
if (!rows.isEmpty()) {
Entity ent = rows.get(0);
ent.setValue("id", actual.getId());
ent.setValue("userRole", actual.getUserRole());
ent.setValue("shortName", actual.getShortName());
ent.setValue("fullName", actual.getFullName());
ent.save();
}
}
/**
* Updates all notifications in database
*
* @param field Field to be updated
* @param value New field value
*/
public void updateAllNotifications(String field, String value) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_NOTIFICATIONS);
for(Entity ent : rows) {
ent.setValue(field, value);
ent.save();
}
}
/**
* Updates a notification in database
*
* @param id Notification code of notification to be updated
* @param field Field to be updated
* @param value New field value
*/
public void updateNotification(long id, String field, String value) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_NOTIFICATIONS, "notifCode = " + id);
for(Entity ent : rows) {
ent.setValue(field, value);
ent.save();
}
}
/**
* Updates a notification in database
*
* @param id Notification code of notification to be updated
* @param actual Updated notification
*/
public void updateNotification(long id, SWADNotification actual) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_NOTIFICATIONS, "notifCode = " + id);
long notifCode = actual.getId();
long eventCode = actual.getEventCode();
String eventType = crypto.encrypt(actual.getEventType());
String eventTime = String.valueOf(actual.getEventTime());
String userNickname = crypto.encrypt(actual.getUserNickname());
String userSurname1 = crypto.encrypt(actual.getUserSurname1());
String userSurname2 = crypto.encrypt(actual.getUserSurname2());
String userFirstname = crypto.encrypt(actual.getUserFirstName());
String userPhoto = crypto.encrypt(actual.getUserPhoto());
String location = crypto.encrypt(actual.getLocation());
String summary = crypto.encrypt(actual.getSummary());
String status = String.valueOf(actual.getStatus());
String content = crypto.encrypt(actual.getContent());
String seenLocal = Utils.parseBoolString(actual.isSeenLocal());
String seenRemote = Utils.parseBoolString(actual.isSeenRemote());
for(Entity ent : rows) {
ent.setValue("notifCode", notifCode);
ent.setValue("eventCode", eventCode);
ent.setValue("eventType", eventType);
ent.setValue("eventTime", eventTime);
ent.setValue("userNickname", userNickname);
ent.setValue("userSurname1", userSurname1);
ent.setValue("userSurname2", userSurname2);
ent.setValue("userFirstname", userFirstname);
ent.setValue("userPhoto", userPhoto);
ent.setValue("location", location);
ent.setValue("summary", summary);
ent.setValue("status", status);
ent.setValue("content", content);
ent.setValue("seenLocal", seenLocal);
ent.setValue("seenRemote", seenRemote);
ent.save();
}
}
/**
* Updates a notification in database
*
* @param prev Notification to be updated
* @param actual Updated notification
*/
public void updateNotification(SWADNotification prev, SWADNotification actual) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_NOTIFICATIONS, "notifCode = " + prev.getId());
long notifCode = actual.getId();
long eventCode = actual.getEventCode();
String eventType = crypto.encrypt(actual.getEventType());
String eventTime = String.valueOf(actual.getEventTime());
String userNickname = crypto.encrypt(actual.getUserNickname());
String userSurname1 = crypto.encrypt(actual.getUserSurname1());
String userSurname2 = crypto.encrypt(actual.getUserSurname2());
String userFirstname = crypto.encrypt(actual.getUserFirstName());
String userPhoto = crypto.encrypt(actual.getUserPhoto());
String location = crypto.encrypt(actual.getLocation());
String summary = crypto.encrypt(actual.getSummary());
String status = String.valueOf(actual.getStatus());
String content = crypto.encrypt(actual.getContent());
String seenLocal = Utils.parseBoolString(actual.isSeenLocal());
String seenRemote = Utils.parseBoolString(actual.isSeenRemote());
for(Entity ent : rows) {
ent.setValue("notifCode", notifCode);
ent.setValue("eventCode", eventCode);
ent.setValue("eventType", eventType);
ent.setValue("eventTime", eventTime);
ent.setValue("userNickname", userNickname);
ent.setValue("userSurname1", userSurname1);
ent.setValue("userSurname2", userSurname2);
ent.setValue("userFirstname", userFirstname);
ent.setValue("userPhoto", userPhoto);
ent.setValue("location", location);
ent.setValue("summary", summary);
ent.setValue("status", status);
ent.setValue("content", content);
ent.setValue("seenLocal", seenLocal);
ent.setValue("seenRemote", seenRemote);
ent.save();
}
}
/**
* Updates a test question in database
*
* @param prev Test question to be updated
* @param actual Updated test question
* @param selectedCourseCode Course code to be referenced
*/
public void updateTestQuestion(TestQuestion prev, TestQuestion actual, long selectedCourseCode) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_TEST_QUESTIONS, "id = " + prev.getId());
Entity ent = rows.get(0);
ent.setValue("id", actual.getId());
ent.setValue("ansType", actual.getAnswerType());
ent.setValue("stem", actual.getStem());
ent.setValue("shuffle", Utils.parseBoolString(actual.getShuffle()));
ent.setValue("feedback", actual.getFeedback());
ent.save();
rows = db.getEntityList(DataBaseHelper.DB_TABLE_TEST_QUESTIONS_COURSE, "qstCod = " + actual.getId());
for (Entity row : rows) {
ent = row;
ent.setValue("crsCod", selectedCourseCode);
ent.save();
}
}
/**
* Updates a test question in database
*
* @param actual Updated test question
* @param selectedCourseCode Course code to be referenced
*/
public void updateTestQuestion(TestQuestion actual, long selectedCourseCode) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_TEST_QUESTIONS, "id = " + actual.getId());
Entity ent = rows.get(0);
ent.setValue("ansType", actual.getAnswerType());
ent.setValue("stem", actual.getStem());
ent.setValue("shuffle", Utils.parseBoolString(actual.getShuffle()));
ent.setValue("feedback", actual.getFeedback());
ent.save();
rows = db.getEntityList(DataBaseHelper.DB_TABLE_TEST_QUESTIONS_COURSE, "qstCod = " + actual.getId());
for (Entity row : rows) {
ent = row;
ent.setValue("crsCod", selectedCourseCode);
ent.save();
}
}
/**
* Updates a test answer in database
*
* @param prev Test answer to be updated
* @param actual Updated test answer
* @param qstCod Test question code to be referenced
*/
public void updateTestAnswer(TestAnswer prev, TestAnswer actual, int qstCod) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_TEST_ANSWERS, "_id = " + prev.getId());
Entity ent = rows.get(0);
ent.setValue("ansInd", actual.getAnsInd());
ent.setValue("answer", actual.getAnswer());
ent.setValue("correct", actual.getCorrect());
ent.setValue("answerFeedback", actual.getFeedback());
ent.save();
rows = db.getEntityList(DataBaseHelper.DB_TABLE_TEST_QUESTION_ANSWERS, "ansCod = " + actual.getId());
for (Entity row : rows) {
ent = row;
ent.setValue("qstCod", qstCod);
ent.save();
}
}
/**
* Updates a test answer in database
*
* @param actual Updated test answer
* @param qstCod Test question code to be referenced
*/
public void updateTestAnswer(TestAnswer actual, int qstCod) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_TEST_ANSWERS, "_id = " + actual.getId());
Entity ent = rows.get(0);
ent.setValue("ansInd", actual.getAnsInd());
ent.setValue("answer", actual.getAnswer());
ent.setValue("correct", actual.getCorrect());
ent.setValue("answerFeedback", actual.getFeedback());
ent.save();
rows = db.getEntityList(DataBaseHelper.DB_TABLE_TEST_QUESTION_ANSWERS, "ansCod = " + actual.getId());
for (Entity row : rows) {
ent = row;
ent.setValue("qstCod", qstCod);
ent.save();
}
}
/**
* Updates a test tag in database
*
* @param prev Test tag to be updated
* @param actual Updated test tag
*/
public void updateTestTag(TestTag prev, TestTag actual) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_TEST_TAGS, "id = " + prev.getId());
Entity ent = rows.get(0);
List<Integer> qstCodList = actual.getQstCodList();
SQLiteStatement st = db.getDB().compileStatement("INSERT OR REPLACE INTO " +
DataBaseHelper.DB_TABLE_TEST_QUESTION_TAGS + " VALUES (NULL, ?, ?, ?);");
ent.setValue("id", actual.getId());
ent.setValue("tagTxt", actual.getTagTxt());
ent.save();
for (Integer i : qstCodList) {
st.bindLong(1, i);
st.bindLong(2, actual.getId());
st.bindLong(3, actual.getTagInd());
st.executeInsert();
}
}
/**
* Updates a test tag in database
*
* @param actual Updated test tag
*/
public void updateTestTag(TestTag actual) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_TEST_TAGS, "id = " + actual.getId());
Entity ent = rows.get(0);
List<Integer> qstCodList = actual.getQstCodList();
SQLiteStatement st = db.getDB().compileStatement("INSERT OR REPLACE INTO " +
DataBaseHelper.DB_TABLE_TEST_QUESTION_TAGS + " VALUES (NULL, ?, ?, ?);");
ent.setValue("id", actual.getId());
ent.setValue("tagTxt", actual.getTagTxt());
ent.save();
for (Integer i : qstCodList) {
st.bindLong(1, i);
st.bindLong(2, actual.getId());
st.bindLong(3, actual.getTagInd());
st.executeInsert();
}
}
/**
* Updates a test config in database
*
* @param id ID of the test prior to update
* @param actual Updated test
*/
public void updateTestConfig(long id, Test actual) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_TEST_CONFIG, "id = " + id);
Entity ent = rows.get(0);
ent.setValue("id", actual.getId());
ent.setValue("min", actual.getMin());
ent.setValue("def", actual.getDef());
ent.setValue("max", actual.getMax());
ent.setValue("feedback", actual.getFeedback());
ent.setValue("editTime", actual.getEditTime());
ent.save();
}
/**
* Updates a relation in database
*
* @param prev Relation to be updated
* @param actual Updated relation
*/
void updatePairTable(PairTable<?, ?> prev, PairTable<?, ?> actual) {
String table = prev.getTable();
String where;
//Integer first = (Integer) prev.getFirst();
//Integer second = (Integer) prev.getSecond();
Pair<String, String> params = selectParamsPairTable(table);
where = params.getFirst() + " = " + prev.getFirst() + " AND " + params.getSecond() + " = " + prev.getSecond();
List<Entity> rows = db.getEntityList(table, where);
if (!rows.isEmpty()) {
Entity ent = rows.get(0);
ent.setValue(params.getFirst(), actual.getFirst());
ent.setValue(params.getSecond(), actual.getSecond());
ent.save();
}
}
/**
* Updates a user in database
*
* @param prev User to be updated
* @param actual Updated user
*/
public void updateUser(User prev, User actual) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_USERS, "id = " + prev.getId());
Entity ent = rows.get(0);
ent.setValue("userCode", actual.getId());
ent.setValue("userID", actual.getUserID());
ent.setValue("userNickname", actual.getUserNickname());
ent.setValue("userSurname1", actual.getUserSurname1());
ent.setValue("userSurname2", actual.getUserSurname2());
ent.setValue("userFirstname", actual.getUserFirstname());
ent.setValue("userPhoto", actual.getUserPhoto());
ent.setValue("userRole", actual.getUserRole());
ent.save();
}
/**
* Updates a user in database
*
* @param eventCode Code of event to be updated
* @param status Event status to be updated
*/
public void updateEventStatus(int eventCode, String status) {
Entity ent = db.getTopEntity(DataBaseHelper.DB_TABLE_EVENTS_ATTENDANCES,
"id = " + eventCode, "1");
ent.setValue("status", crypto.encrypt(status));
ent.save();
}
/**
* Updates a Group and the relationship between Groups and Courses
*
* @param groupCode code of the group to be updated
* @param courseCode current code of the course related to the group
* @param currentGroup updated group
*/
public boolean updateGroup(long groupCode, long courseCode, Group currentGroup, long... groupTypeCode) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_GROUPS, "id =" + groupCode);
if (!rows.isEmpty()) {
Entity ent = rows.get(0);
boolean returnValue = true;
insertEntity(DataBaseHelper.DB_TABLE_GROUPS, currentGroup, ent);
rows = db.getEntityList(DataBaseHelper.DB_TABLE_GROUPS_COURSES, "grpCod =" + groupCode);
Course course = getRow(DataBaseHelper.DB_TABLE_COURSES, "id", String.valueOf(courseCode));
//course code is a foreign key. Therefore, to avoid a database error,
//it should not insert/modify rows in the relationship table if the course does not exists
if (course != null) {
if (rows.isEmpty()) {
ent = new Entity(DataBaseHelper.DB_TABLE_GROUPS_COURSES);
ent.setValue("grpCod", groupCode);
ent.setValue("crsCod", courseCode);
ent.save();
} else {
rows.get(0).setValue("crsCod", courseCode);
rows.get(0).save();
}
} else returnValue = false;
if (groupTypeCode.length > 0) {
GroupType groupType = getRow(DataBaseHelper.DB_TABLE_GROUP_TYPES, "id", String.valueOf(groupTypeCode[0]));
//group type code is a foreign key. Therefore, to avoid a database error,
//it should not insert/modify rows in the relationship table if the group type does not exists
if (groupType != null) {
rows = db.getEntityList(DataBaseHelper.DB_TABLE_GROUPS_GROUPTYPES, "grpCod=" + groupCode);
if (!rows.isEmpty()) {
insertPairTable(new PairTable<>(DataBaseHelper.DB_TABLE_GROUPS_GROUPTYPES, groupTypeCode[0], groupCode));
} else {
PairTable<Object, Object> prev = new PairTable<>(DataBaseHelper.DB_TABLE_GROUPS_GROUPTYPES, rows.get(0).getValue("grpTypCod"), rows.get(0).getValue("grpCod"));
PairTable<Object, Object> current = new PairTable<Object, Object>(DataBaseHelper.DB_TABLE_GROUPS_GROUPTYPES, groupTypeCode[0], groupCode);
updatePairTable(prev, current);
}
} else returnValue = false;
}
return returnValue;
} else
return false;
}
/**
* Updates a Frequent Recipient with the new score
*
* @param nickname the identifier of recipient
* @param score the score to order the frequent recipients list
*/
public void updateFrequentRecipient(String nickname, Double score) {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_FREQUENT_RECIPIENTS, "nicknameRecipient = '" + nickname + "'");
for(Entity ent : rows) {
ent.setValue("score", score);
ent.save();
}
}
/**
* Removes a User from database
*
* @param u User to be removed
*/
public void removeUser(User u) {
removeRow(DataBaseHelper.DB_TABLE_USERS, u.getId());
}
/**
* Removes a Group from database
*
* @param g Group to be removed
*/
public void removeGroup(Group g) {
removeRow(DataBaseHelper.DB_TABLE_GROUPS, g.getId());
//Remove also relationships with courses and group types
removeAllRows(DataBaseHelper.DB_TABLE_GROUPS_GROUPTYPES, "grpCod", g.getId());
removeAllRows(DataBaseHelper.DB_TABLE_GROUPS_COURSES, "grpCod", g.getId());
}
/**
* Removes a row from a database table
*
* @param id Identifier of row to be removed
*/
public void removeRow(String table, long id) {
List<Entity> rows = db.getEntityList(table, "id = " + id);
Entity ent = rows.get(0);
ent.delete();
}
/**
* Removes all rows from a database table where fieldName has the given value as value
*
* @param fieldName Name field to search
* @param value Value field of row to be removed
*/
public void removeAllRows(String table, String fieldName, Object value) {
List<Entity> rows;
if(value instanceof String) {
rows = db.getEntityList(table, fieldName + "='" + value + "'");
} else {
rows = db.getEntityList(table, fieldName + "= " + value);
}
for (Entity ent : rows) {
ent.delete();
}
}/**
* Removes all rows from a database table matching the given condition
*
* @param where condition to remove a row
* @return numRowsDeleted Number of deleted rows
*/
public int removeAllRows(String table, String where) {
List<Entity> rows = db.getEntityList(table, where);
for (Entity ent : rows) {
ent.delete();
}
return rows.size();
}
/**
* Removes a PairTable from database
*
* @param p PairTable to be removed
*/
public void removePairTable(PairTable<?, ?> p) {
String table = p.getTable();
Integer first = (Integer) p.getFirst();
Integer second = (Integer) p.getSecond();
String where;
List<Entity> rows;
Entity ent;
Pair<String, String> params = selectParamsPairTable(table);
where = params.getFirst() + " = " + first + " AND " + params.getSecond() + " = " + second;
rows = db.getEntityList(table, where);
ent = rows.get(0);
ent.delete();
}
/**
* Gets a field of last notification
*
* @param field A field of last notification
* @return The field of last notification
*/
public String getFieldOfLastNotification(String field) {
String where = null;
String orderby = "eventTime DESC";
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_NOTIFICATIONS, where, orderby);
String f = "0";
if (rows.size() > 0) {
Entity ent = rows.get(0);
f = (String) ent.getValue(field);
}
return f;
}
/**
* Gets last time the test was updated
*
* @param selectedCourseCode Test's course
* @return Last time the test was updated
*/
public String getTimeOfLastTestUpdate(long selectedCourseCode) {
String where = "id=" + selectedCourseCode;
String orderby = null;
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_TEST_CONFIG, where, orderby);
String f = "0";
if (rows.size() > 0) {
Entity ent = rows.get(0);
f = (String) ent.getValue("editTime");
}
if (f == null) {
f = "0";
}
return f;
}
/**
* Gets the tags of specified course ordered by tagInd field
*
* @param selectedCourseCode Test's course
* @return A list of the tags of specified course ordered by tagInd field
*/
public List<TestTag> getOrderedCourseTags(long selectedCourseCode) {
String[] columns = {"T.id", "T.tagTxt", "Q.qstCod", "Q.tagInd"};
String tables = DataBaseHelper.DB_TABLE_TEST_TAGS + " AS T, " + DataBaseHelper.DB_TABLE_TEST_QUESTION_TAGS
+ " AS Q, " + DataBaseHelper.DB_TABLE_TEST_QUESTIONS_COURSE + " AS C";
String where = "T.id=Q.tagCod AND Q.qstCod=C.qstCod AND C.crsCod=" + selectedCourseCode;
String orderBy = "T.tagTxt ASC";
String groupBy = "T.id";
Cursor dbCursor = db.getDB().query(tables, columns, where, null, groupBy, null, orderBy);
List<TestTag> result = new ArrayList<>();
List<Integer> qstCodList;
int idOld = -1;
TestTag t = null;
while (dbCursor.moveToNext()) {
int id = dbCursor.getInt(0);
if (id != idOld) {
qstCodList = new ArrayList<>();
String tagTxt = dbCursor.getString(1);
qstCodList.add(dbCursor.getInt(2));
int tagInd = dbCursor.getInt(3);
t = new TestTag(id, qstCodList, tagTxt, tagInd);
result.add(t);
idOld = id;
} else {
t.addQstCod(dbCursor.getInt(2));
}
}
dbCursor.close();
return result;
}
/**
* Gets the questions of specified course and tags
*
* @param selectedCourseCode Test's course
* @param tagsList Tag's list of the questions to be extracted
* @return A list of the questions of specified course and tags
*/
public List<TestQuestion> getRandomCourseQuestionsByTagAndAnswerType(long selectedCourseCode, List<TestTag> tagsList,
List<String> answerTypesList, int maxQuestions) {
String select = "SELECT DISTINCT Q.id, Q.ansType, Q.shuffle, Q.stem, Q.feedback";
String tables = " FROM " + DataBaseHelper.DB_TABLE_TEST_QUESTIONS + " AS Q, "
+ DataBaseHelper.DB_TABLE_TEST_QUESTIONS_COURSE + " AS C, "
+ DataBaseHelper.DB_TABLE_TEST_QUESTION_TAGS + " AS T";
String where = " WHERE Q.id=C.qstCod AND Q.id=T.qstCod AND C.crsCod=" + selectedCourseCode;
String orderby = " ORDER BY RANDOM()";
String limit = " LIMIT " + maxQuestions;
Cursor dbCursorQuestions, dbCursorAnswers;
List<TestQuestion> result = new ArrayList<>();
List<TestAnswer> answers;
int tagsListSize = tagsList.size();
int answerTypesListSize = answerTypesList.size();
if (!tagsList.get(0).getTagTxt().equals("all")) {
where += " AND (";
for (int i = 0; i < tagsListSize; i++) {
where += "T.tagCod=" + tagsList.get(i).getId();
if (i < tagsListSize - 1) {
where += " OR ";
}
}
where += ")";
if (!answerTypesList.get(0).equals("all")) {
where += " AND ";
}
}
if (!answerTypesList.get(0).equals("all")) {
if (tagsList.get(0).getTagTxt().equals("all")) {
where += " AND ";
}
where += "(";
for (int i = 0; i < answerTypesListSize; i++) {
where += "Q.ansType='" + answerTypesList.get(i) + "'";
if (i < answerTypesListSize - 1) {
where += " OR ";
}
}
where += ")";
}
dbCursorQuestions = db.getDB().rawQuery(select + tables + where + orderby + limit, null);
select = "SELECT DISTINCT A._id, A.ansInd, A.answer, A.correct, A.answerFeedback";
tables = " FROM " + DataBaseHelper.DB_TABLE_TEST_ANSWERS + " AS A, "
+ DataBaseHelper.DB_TABLE_TEST_QUESTION_ANSWERS + " AS Q";
orderby = " ORDER BY A.ansInd";
while (dbCursorQuestions.moveToNext()) {
int qstCod = dbCursorQuestions.getInt(0);
String ansType = dbCursorQuestions.getString(1);
boolean shuffle = Utils.parseStringBool(dbCursorQuestions.getString(2));
String stem = dbCursorQuestions.getString(3);
String questionFeedback = dbCursorQuestions.getString(4);
TestQuestion q = new TestQuestion(qstCod, selectedCourseCode, stem, ansType, shuffle, questionFeedback);
where = " WHERE Q.qstCod=" + qstCod + " AND Q.ansCod=A._id";
dbCursorAnswers = db.getDB().rawQuery(select + tables + where + orderby, null);
answers = new ArrayList<>();
while (dbCursorAnswers.moveToNext()) {
long ansCod = dbCursorAnswers.getLong(0);
int ansInd = dbCursorAnswers.getInt(1);
String answer = dbCursorAnswers.getString(2);
boolean correct = dbCursorAnswers.getString(3).equals("true");
String aswerFeedback = dbCursorAnswers.getString(4);
answers.add(new TestAnswer(ansCod, ansInd, qstCod, correct, answer, aswerFeedback));
}
q.setAnswers(answers);
result.add(q);
dbCursorAnswers.close();
}
dbCursorQuestions.close();
return result;
}
/**
* Clean old notifications by size
*
* @param size Max table size
*/
public void cleanOldNotificationsBySize(int size) {
String where = null;
String orderby = "CAST(eventTime as INTEGER) ASC";
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_NOTIFICATIONS, where, orderby);
int numRows = rows.size();
int numDeletions = numRows - size;
if (numRows > size) {
for (int i = 0; i < numDeletions; i++)
rows.get(i).delete();
}
}
/**
* Clean old notifications by age
*
* @param age Max age in seconds
* @return numRowsDeleted Number of deleted notifications
*/
public int cleanOldNotificationsByAge(int age) {
long now = Calendar.getInstance().getTime().getTime() / 1000; // in seconds
// Remove notifications older than 'age' seconds
String where = "CAST(eventTime as INTEGER) < " + String.valueOf(now - age);
return removeAllRows(DataBaseHelper.DB_TABLE_NOTIFICATIONS, where);
}
/**
* Encrypts the notifications data
*/
public void encryptNotifications() {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_NOTIFICATIONS);
for (Entity ent : rows) {
ent.setValue("eventType", crypto.encrypt(ent.getString("eventType")));
ent.setValue("userSurname1", crypto.encrypt(ent.getString("userSurname1")));
ent.setValue("userSurname2", crypto.encrypt(ent.getString("userSurname2")));
ent.setValue("userFirstname", crypto.encrypt(ent.getString("userFirstname")));
ent.setValue("userPhoto", crypto.encrypt(ent.getString("userPhoto")));
ent.setValue("location", crypto.encrypt(ent.getString("location")));
ent.setValue("summary", crypto.encrypt(ent.getString("summary")));
ent.setValue("content", crypto.encrypt(ent.getString("content")));
ent.save();
}
}
/**
* Encrypts the users data
*/
public void encryptUsers() {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_USERS);
for (Entity ent : rows) {
ent.setValue("userID", crypto.encrypt(ent.getString("userID")));
ent.setValue("userNickname", crypto.encrypt(ent.getString("userNickname")));
ent.setValue("userSurname1", crypto.encrypt(ent.getString("userSurname1")));
ent.setValue("userSurname2", crypto.encrypt(ent.getString("userSurname2")));
ent.setValue("userFirstname", crypto.encrypt(ent.getString("userFirstname")));
ent.setValue("userPhoto", crypto.encrypt(ent.getString("photoPath")));
ent.save();
}
}
/**
* Reencrypts the notifications data
*/
public void reencryptNotifications() {
List<Entity> rows = db.getEntityList(DataBaseHelper.DB_TABLE_NOTIFICATIONS);
String type, surname1, surname2, firstname, photo, location, summary, content;
for (Entity ent : rows) {
type = crypto.encrypt(OldCrypto.decrypt(mCtx, DBKey, ent.getString("eventType")));
surname1 = crypto.encrypt(OldCrypto.decrypt(mCtx, DBKey, ent.getString("userSurname1")));
surname2 = crypto.encrypt(OldCrypto.decrypt(mCtx, DBKey, ent.getString("userSurname2")));
firstname = crypto.encrypt(OldCrypto.decrypt(mCtx, DBKey, ent.getString("userFirstname")));
photo = crypto.encrypt(OldCrypto.decrypt(mCtx, DBKey, ent.getString("userPhoto")));
location = crypto.encrypt(OldCrypto.decrypt(mCtx, DBKey, ent.getString("location")));
summary = crypto.encrypt(OldCrypto.decrypt(mCtx, DBKey, ent.getString("summary")));
content = crypto.encrypt(OldCrypto.decrypt(mCtx, DBKey, ent.getString("content")));
ent.setValue("eventType", type);
ent.setValue("userSurname1", surname1);
ent.setValue("userSurname2", surname2);
ent.setValue("userFirstname", firstname);
ent.setValue("userPhoto", photo);
ent.setValue("location", location);
ent.setValue("summary", summary);
ent.setValue("content", content);
ent.save();
}
}
/**
* Empty table from database
*
* @param table Table to be emptied
*/
public void emptyTable(String table) {
db.emptyTable(table);
Log.d(TAG, "Emptied table " + table);
}
/**
* Delete table from database
*
* @param table Table to be deleted
*/
public void deleteTable(String table) {
if(isTableExisting(table)) {
db.deleteTable(table);
Log.d(TAG, "Deleted table " + table);
} else {
Log.e(TAG, "Table " + table + " doesn't exists. Can't be deleted");
}
}
/**
* Checks if a table exists in database
* @param tableName Name of the table to be checked
* @return true is table exists
* false otherwise
*/
public boolean isTableExisting(String tableName) {
Cursor cursor = db.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '"+tableName+"'", null);
if(cursor!=null) {
if(cursor.getCount()>0) {
cursor.close();
return true;
}
cursor.close();
}
return false;
}
/**
* Delete all tables from database
*/
public void clearDB() {
db.deleteTables();
Log.i(TAG, "All tables deleted");
}
/**
* Clean data of all tables from database. Removes users photos from external storage
*/
public void cleanTables() {
Log.i(TAG, "Emptying all tables");
db.emptyTables();
compactDB();
Log.i(TAG, "All tables emptied");
}
/**
* Begin a database transaction
*/
public synchronized void beginTransaction() {
while(db.inTransaction()) {
try {
wait();
} catch (InterruptedException e) {
Log.e(TAG, e.getMessage(), e);
}
}
db.startTransaction();
Log.i(TAG, "Database locked");
}
/**
* End a database transaction
*/
public synchronized void endTransaction(boolean successfulTransaction) {
if(db.inTransaction()) {
if(successfulTransaction) {
db.successfulTransaction();
}
db.endTransaction();
Log.i(TAG, "Database unlocked");
notifyAll();
} else {
Exception e = new DataBaseHelperException("No active transactions");
Log.e(TAG, e.getMessage(), e);
}
}
public boolean isDbInTransaction() {
return db.inTransaction();
}
/**
* Compact the database
*/
private void compactDB() {
Log.i(TAG, "Compacting database");
db.getDB().execSQL("VACUUM;");
Log.i(TAG, "Database compacted");
}
/**
* Initializes the database structure for the first use
*/
public void initializeDB() {
//Index for tests
db.getDB().execSQL("CREATE UNIQUE INDEX IF NOT EXISTS " + DataBaseHelper.DB_TABLE_TEST_QUESTION_TAGS + "_unique on "
+ DataBaseHelper.DB_TABLE_TEST_QUESTION_TAGS + "(qstCod, tagCod);");
}
/**
* Upgrades the database structure
*/
public void upgradeDB() {
int dbVersion = db.getDB().getVersion();
Log.i(TAG, "Upgrading database");
/*
* Modify database keeping data:
* 1. Create temporary table __DB_TABLE_GROUPS (with the new model)
* 2. insert in the temporary table all the data (in the new model) from the old table
* 3. drop table DB_TABLE_GROUPS
* 4. create DB_TABLE_GROUPS with the new model.
* 5. insert in DB_TABLE_GROUPS all the data from __DB_TABLE_GROUPS
* 6. insert in DB_TABLE_GROUPS_GROUPTYPES the relationships between the deleted groups and group types
* 7. drop __DB_TABLE_GROUPS
* Just to modify database without to keep data just 7,6.
*
* */
/* version 15-16
* changes on notifications table:
* - new field notifCode
* - changed field id to eventCode
* */
if (dbVersion == 16) {
//without keeping data
db.getDB().execSQL("DROP TABLE " + DataBaseHelper.DB_TABLE_NOTIFICATIONS + ";");
db.getDB().execSQL("CREATE TABLE " + DataBaseHelper.DB_TABLE_NOTIFICATIONS + " (_id integer primary key autoincrement, notifCode long, eventCode long, eventType text, eventTime text,"
+ " userSurname1 text, userSurname2 text, userFirstname text, userPhoto text, location text, summary text, status text, content text, seenLocal text, seenRemote text); ");
}
/* version 16-17
* removed old Rollcall tables
* created indexes for user tables
* */
if (dbVersion == 17) {
deleteTable(DB_TABLE_PRACTICE_SESSIONS);
deleteTable(DB_TABLE_ROLLCALL);
}
/* version 18-19
* deleted old event data
* */
if (dbVersion == 19) {
emptyTable(DB_TABLE_EVENTS_ATTENDANCES);
}
Log.i(TAG, "Database upgraded");
compactDB();
}
/**
* Indicates if the db was cleaned
*/
public static boolean isDbCleaned() {
return dbCleaned;
}
/**
* Set the fact that the db was cleaned
*/
public static void setDbCleaned(boolean state) {
dbCleaned = state;
}
}