/*
This file is part of BeepMe.
BeepMe 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.
BeepMe 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 BeepMe. If not, see <http://www.gnu.org/licenses/>.
Copyright 2012-2014 Michael Glanznig
http://beepme.yourexp.at
*/
package com.glanznig.beepme.db;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import com.glanznig.beepme.data.Sample;
import com.glanznig.beepme.data.Tag;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class SampleTable extends StorageHandler {
private static final String TAG = "SampleTable";
private static final String TBL_NAME = "sample";
private static final String TBL_CREATE =
"CREATE TABLE IF NOT EXISTS " + TBL_NAME + " (" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"timestamp INTEGER NOT NULL UNIQUE, " +
"title TEXT, " +
"description TEXT, " +
"accepted INTEGER NOT NULL, " +
"photoUri TEXT, " +
"uptimeId INTEGER, " + //add NOT NULL
"FOREIGN KEY (uptimeId) REFERENCES " + UptimeTable.getTableName() + " (_id)" +
")";
public SampleTable(Context ctx) {
super(ctx);
}
public static String getTableName() {
return TBL_NAME;
}
public static void createTable(SQLiteDatabase db) {
db.execSQL(TBL_CREATE);
}
public static void dropTable(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + TBL_NAME);
}
public static void truncateTable(SQLiteDatabase db) {
dropTable(db);
createTable(db);
}
public Sample getSample(long id) {
SQLiteDatabase db = getDb();
Sample s = null;
Cursor cursor = db.query(TBL_NAME, new String[] {"_id", "timestamp", "title", "description", "accepted",
"photoUri", "uptimeId"},
"_id=?", new String[] { String.valueOf(id) }, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
s = new Sample(cursor.getLong(0));
long timestamp = cursor.getLong(1);
s.setTimestamp(new Date(timestamp));
if (!cursor.isNull(2)) {
s.setTitle(cursor.getString(2));
}
if (!cursor.isNull(3)) {
s.setDescription(cursor.getString(3));
}
if (cursor.getInt(4) == 0) {
s.setAccepted(false);
}
else {
s.setAccepted(true);
}
if (!cursor.isNull(5)) {
s.setPhotoUri(cursor.getString(5));
}
if (!cursor.isNull(6)) {
s.setUptimeId(cursor.getLong(6));
}
}
cursor.close();
db.close();
return s;
}
public Sample getSampleWithTags(long id) {
Sample s = getSample(id);
if (s != null) {
List<Tag> tagList = getTagsOfSample(s.getId());
if (tagList != null) {
Iterator<Tag> i = tagList.iterator();
while (i.hasNext()) {
s.addTag(i.next());
}
}
}
return s;
}
public List<Tag> getTagsOfSample(long id) {
if (id != 0L) {
ArrayList<Tag> tagList = new ArrayList<Tag>();
SQLiteDatabase db = getDb();
Cursor cursor = db.rawQuery("SELECT t._id, t.name, t.vocabulary_id FROM " + TagTable.getTableName() + " t " +
"INNER JOIN " + SampleTagTable.getTableName() + " st ON st.tag_id = t._id WHERE st.sample_id = ?",
new String[] { String.valueOf(id) });
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
Tag t = null;
do {
t = new Tag(cursor.getLong(0));
t.setName(cursor.getString(1));
t.setVocabularyId(cursor.getLong(2));
tagList.add(t);
}
while (cursor.moveToNext());
cursor.close();
db.close();
return tagList;
}
else if (cursor != null) {
cursor.close();
}
db.close();
}
return null;
}
public List<Sample> getSamples() {
return getSamples(false);
}
public List<Sample> getSamples(boolean declined) {
SQLiteDatabase db = getDb();
List<Sample> sampleList = new ArrayList<Sample>();
String where = null;
if (declined == false) {
where = "accepted = 1";
}
Cursor cursor = db.query(getTableName(), new String[] {"_id", "timestamp", "title", "description",
"accepted", "photoUri", "uptimeId"}, where, null, null, null, "timestamp DESC");
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
do {
Sample s = new Sample(cursor.getLong(0));
long timestamp = cursor.getLong(1);
s.setTimestamp(new Date(timestamp));
if (!cursor.isNull(2)) {
s.setTitle(cursor.getString(2));
}
if (!cursor.isNull(3)) {
s.setDescription(cursor.getString(3));
}
if (cursor.getInt(4) == 0) {
s.setAccepted(false);
}
else {
s.setAccepted(true);
}
if (!cursor.isNull(5)) {
s.setPhotoUri(cursor.getString(5));
}
if (!cursor.isNull(6)) {
s.setUptimeId(cursor.getLong(6));
}
sampleList.add(s);
}
while (cursor.moveToNext());
cursor.close();
}
db.close();
return sampleList;
}
public List<Long> getSampleIds() {
SQLiteDatabase db = getDb();
List<Long> idList = new ArrayList<Long>();
Cursor cursor = db.query(getTableName(), new String[] {"_id"}, "accepted = 1", null, null, null, "timestamp DESC");
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
do {
idList.add(cursor.getLong(0));
}
while (cursor.moveToNext());
cursor.close();
}
db.close();
return idList;
}
public Sample addSample(Sample s) {
Sample sCreated = null;
if (s != null) {
boolean success = true;
SQLiteDatabase db = getDb();
ContentValues values = new ContentValues();
if (s.getTimestamp() != null) {
values.put("timestamp", String.valueOf(s.getTimestamp().getTime()));
}
else {
success = false;
}
values.put("title", s.getTitle());
values.put("description", s.getDescription());
if (s.getAccepted()) {
values.put("accepted", "1");
}
else {
values.put("accepted", "0");
}
values.put("photoUri", s.getPhotoUri());
values.put("uptimeId", s.getUptimeId());
if (success) {
long sampleId = db.insert(getTableName(), null, values);
sCreated = new Sample(sampleId);
sCreated.setAccepted(s.getAccepted());
if (s.getDescription() != null) {
sCreated.setDescription(s.getDescription());
}
if (s.getPhotoUri() != null) {
sCreated.setPhotoUri(s.getPhotoUri());
}
if (s.getTimestamp() != null) {
sCreated.setTimestamp(s.getTimestamp());
}
if (s.getTitle() != null) {
sCreated.setTitle(s.getTitle());
}
if (s.getUptimeId() != 0L) {
sCreated.setUptimeId(s.getUptimeId());
}
}
db.close();
if (s.getTags().size() > 0) {
Iterator<Tag> i = s.getTags().iterator();
TagTable tt = new TagTable(this.getContext());
while (i.hasNext()) {
Tag t = i.next();
sCreated.addTag(tt.addTag(t.getVocabularyId(), t.getName(), s.getId()));
}
}
}
return sCreated;
}
public boolean editSample(Sample s) {
SQLiteDatabase db = getDb();
TagTable tt = new TagTable(this.getContext());
ContentValues values = new ContentValues();
values.put("title", s.getTitle());
values.put("description", s.getDescription());
if (s.getAccepted()) {
values.put("accepted", "1");
}
else {
values.put("accepted", "0");
}
values.put("photoUri", s.getPhotoUri());
values.put("uptimeId", s.getUptimeId());
int numRows = db.update(getTableName(), values, "_id=?", new String[] { String.valueOf(s.getId()) });
db.close();
List<Tag> dbTagList = getTagsOfSample(s.getId());
List<Tag> sTagList = s.getTags();
if (sTagList.size() == 0 && dbTagList != null) {
//delete all
Iterator<Tag> i = dbTagList.iterator();
while (i.hasNext()) {
Tag t = i.next();
tt.removeTag(t.getVocabularyId(), t.getName(), s.getId());
}
}
else if (sTagList.size() > 0 && dbTagList == null) {
//add all
Iterator<Tag> i = sTagList.iterator();
while (i.hasNext()) {
Tag t = i.next();
tt.addTag(t.getVocabularyId(), t.getName(), s.getId());
}
}
else if (sTagList.size() > 0 && dbTagList != null) {
//sync, if changes
if (!sTagList.equals(dbTagList)) {
HashSet<String> sTagSet = new HashSet<String>();
Iterator<Tag> i = sTagList.iterator();
while (i.hasNext()) {
Tag t = i.next();
sTagSet.add(t.getName());
}
HashSet<String> dbTagSet = new HashSet<String>();
i = dbTagList.iterator();
while (i.hasNext()) {
Tag t = i.next();
dbTagSet.add(t.getName());
}
//sample side
i = sTagList.iterator();
while (i.hasNext()) {
Tag t = i.next();
if (!dbTagSet.contains(t.getName())) {
tt.addTag(t.getVocabularyId(), t.getName(), s.getId());
}
}
//db side
i = dbTagList.iterator();
while (i.hasNext()) {
Tag t = i.next();
if (!sTagSet.contains(t.getName())) {
tt.removeTag(t.getVocabularyId(), t.getName(), s.getId());
}
}
}
}
return numRows == 1;
}
public List<Sample> getSamplesOfDay(Calendar day) {
if (day.isSet(Calendar.YEAR) && day.isSet(Calendar.MONTH) && day.isSet(Calendar.DAY_OF_MONTH)) {
ArrayList<Sample> list = new ArrayList<Sample>();
SQLiteDatabase db = getDb();
long startOfDay = day.getTimeInMillis();
day.roll(Calendar.DAY_OF_MONTH, true);
long endOfDay = day.getTimeInMillis();
day.roll(Calendar.DAY_OF_MONTH, false);
Cursor cursor = db.query(getTableName(), new String[] {"_id", "timestamp", "title", "description",
"accepted", "photoUri", "uptimeId"}, "timestamp between ? and ?",
new String[] { String.valueOf(startOfDay), String.valueOf(endOfDay) }, null, null, "timestamp DESC");
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
do {
Sample s = new Sample(cursor.getLong(0));
long timestamp = cursor.getLong(1);
s.setTimestamp(new Date(timestamp));
if (!cursor.isNull(2)) {
s.setTitle(cursor.getString(2));
}
if (!cursor.isNull(3)) {
s.setDescription(cursor.getString(3));
}
if (cursor.getInt(4) == 0) {
s.setAccepted(false);
}
else {
s.setAccepted(true);
}
if (!cursor.isNull(5)) {
s.setPhotoUri(cursor.getString(5));
}
if (!cursor.isNull(6)) {
s.setUptimeId(cursor.getLong(6));
}
list.add(s);
}
while (cursor.moveToNext());
cursor.close();
return list;
}
}
return null;
}
public int getNumAcceptedToday() {
int count = 0;
SQLiteDatabase db = getDb();
Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH);
int day = now.get(Calendar.DAY_OF_MONTH);
GregorianCalendar today = new GregorianCalendar(year, month, day);
long startOfDay = today.getTimeInMillis();
today.roll(Calendar.DAY_OF_MONTH, true);
long endOfDay = today.getTimeInMillis();
today.roll(Calendar.DAY_OF_MONTH, false);
Cursor cursor = db.query(getTableName(), new String[] {"_id"}, "timestamp between ? and ? and accepted = 1",
new String[] { String.valueOf(startOfDay), String.valueOf(endOfDay) }, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
count = cursor.getCount();
cursor.close();
}
db.close();
return count;
}
public int getSampleCountToday() {
int count = 0;
SQLiteDatabase db = getDb();
Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH);
int day = now.get(Calendar.DAY_OF_MONTH);
GregorianCalendar today = new GregorianCalendar(year, month, day);
long startOfDay = today.getTimeInMillis();
today.roll(Calendar.DAY_OF_MONTH, true);
long endOfDay = today.getTimeInMillis();
today.roll(Calendar.DAY_OF_MONTH, false);
Cursor cursor = db.query(getTableName(), new String[] {"accepted"}, "timestamp between ? and ?",
new String[] { String.valueOf(startOfDay), String.valueOf(endOfDay) }, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
count = cursor.getCount();
cursor.close();
}
db.close();
return count;
}
public double getRatioAcceptedToday() {
int count = 0;
int accepted = 0;
SQLiteDatabase db = getDb();
Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH);
int day = now.get(Calendar.DAY_OF_MONTH);
GregorianCalendar today = new GregorianCalendar(year, month, day);
long startOfDay = today.getTimeInMillis();
today.roll(Calendar.DAY_OF_MONTH, true);
long endOfDay = today.getTimeInMillis();
today.roll(Calendar.DAY_OF_MONTH, false);
Cursor cursor = db.query(getTableName(), new String[] {"accepted"}, "timestamp between ? and ?",
new String[] { String.valueOf(startOfDay), String.valueOf(endOfDay) }, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
do {
count += 1;
if (cursor.getInt(0) == 1) {
accepted += 1;
}
}
while (cursor.moveToNext());
cursor.close();
}
db.close();
if (count == 0) {
return 0;
}
return accepted/count;
}
}