/*
EventSessionDao.java
Copyright (c) 2014 NTT DOCOMO,INC.
Released under the MIT license
http://opensource.org/licenses/mit-license.php
*/
package org.deviceconnect.android.event.cache.db;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import org.deviceconnect.android.event.Event;
import org.deviceconnect.android.event.EventError;
import org.deviceconnect.android.event.cache.Utils;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
/**
* EventSessionテーブル用DAOクラス.
*
*
* @author NTT DOCOMO, INC.
*/
final class EventSessionDao implements EventSessionSchema {
/**
* Utilityクラスなのでprivate.
*/
private EventSessionDao() {
}
/**
* EventSessionテーブルのデータクラス.
*
* @author NTT DOCOMO, INC.
*
*/
static class EventSession {
/**
* ID.
*/
long mId;
/**
* EventDeviceテーブルのID.
*/
long mEdId;
/**
* ClientテーブルのID.
*/
long mCId;
/**
* 作成日.
*/
Timestamp mCreateDate;
/**
* 更新日.
*/
Timestamp mUpdateDate;
}
/**
* イベントとセッションデータのマッチング情報を登録する.
*
* @param db データベース操作オブジェクト
* @param eventServiceId EventDeviceテーブルのID
* @param clientId ClientテーブルのID
* @return 登録出来た場合は登録時のIDを返す。重複している場合は登録済みのIDを返す。処理に失敗した場合は-1を返す。
*/
static long insert(final SQLiteDatabase db, final long eventServiceId, final long clientId) {
long result = -1L;
Cursor cursor = db.query(TABLE_NAME, new String[] {_ID}, ED_ID + "=? AND " + C_ID + "=?",
new String[] {"" + eventServiceId, "" + clientId}, null, null, null);
if (cursor.getCount() == 0) {
ContentValues values = new ContentValues();
values.put(ED_ID, eventServiceId);
values.put(C_ID, clientId);
values.put(CREATE_DATE, Utils.getCurreTimestamp().getTime());
values.put(UPDATE_DATE, Utils.getCurreTimestamp().getTime());
result = db.insert(TABLE_NAME, null, values);
} else if (cursor.moveToFirst()) {
if (cursor.getColumnIndex(_ID) != -1) {
result = cursor.getLong(0);
}
}
cursor.close();
return result;
}
/**
* 指定されたイベント情報を削除する.
*
* @param db データベース操作オブジェクト
* @param event イベントデータ
* @return 処理結果
*/
static EventError delete(final SQLiteDatabase db, final Event event) {
EventSession data = get(db, event);
if (data == null) {
return EventError.NOT_FOUND;
}
int count = db.delete(TABLE_NAME, _ID + "=?", new String[] {"" + data.mId});
if (count == 0) {
return EventError.NOT_FOUND;
} else if (count != 1) {
return EventError.FAILED;
}
Cursor c = db.query(TABLE_NAME, new String[] {_ID}, ED_ID + "=?",
new String[] {"" + data.mEdId}, null, null, null);
if (c.getCount() == 0) {
// デバイスに紐づくセッション情報がなくなったので削除
count = EventDeviceDao.deleteById(db, data.mEdId);
if (count != 1) {
c.close();
return EventError.FAILED;
}
}
c.close();
return EventError.NONE;
}
/**
* 指定されたIDを持つ行を削除する.
*
* @param db データベース操作オブジェクト
* @param ids 削除するID一覧
* @return 処理結果
*/
static EventError delete(final SQLiteDatabase db, final String[] ids) {
try {
StringBuilder in = new StringBuilder();
for (int i = 0; i < ids.length; i++) {
in.append("?");
if (i != ids.length - 1) {
in.append(",");
}
}
int count = db.delete(TABLE_NAME, C_ID + " IN (" + in.toString() + ")", ids);
if (count == 0) {
return EventError.NOT_FOUND;
}
} catch (SQLiteException e) {
return EventError.FAILED;
}
return EventError.NONE;
}
/**
* 指定されたイベント情報からidを取得する.
*
* @param db データベース操作オブジェクト
* @param event イベントデータ
* @return 見つかった場合は行のデータ、その他はnullを返す。
*/
static EventSession get(final SQLiteDatabase db, final Event event) {
EventSession result = null;
StringBuilder sb = new StringBuilder();
String join = " INNER JOIN ";
String prepared = " = ? ";
String and = " AND ";
sb.append("SELECT es.");
sb.append(_ID);
sb.append(", es.");
sb.append(ED_ID);
sb.append(", es.");
sb.append(C_ID);
sb.append(", es.");
sb.append(CREATE_DATE);
sb.append(", es.");
sb.append(UPDATE_DATE);
sb.append(" FROM ");
sb.append(ProfileSchema.TABLE_NAME);
sb.append(" as p");
sb.append(join);
sb.append(InterfaceSchema.TABLE_NAME);
sb.append(" as i ON p.");
sb.append(ProfileSchema._ID);
sb.append(" = i.");
sb.append(InterfaceSchema.P_ID);
sb.append(join);
sb.append(AttributeSchema.TABLE_NAME);
sb.append(" as a ON i.");
sb.append(InterfaceSchema._ID);
sb.append(" = a.");
sb.append(AttributeSchema.I_ID);
sb.append(join);
sb.append(EventDeviceSchema.TABLE_NAME);
sb.append(" as ed ON a.");
sb.append(AttributeSchema._ID);
sb.append(" = ed.");
sb.append(EventDeviceSchema.A_ID);
sb.append(join);
sb.append(DeviceSchema.TABLE_NAME);
sb.append(" as d ON ed.");
sb.append(EventDeviceSchema.D_ID);
sb.append(" = d.");
sb.append(DeviceSchema._ID);
sb.append(join);
sb.append(EventSessionSchema.TABLE_NAME);
sb.append(" as es ON es.");
sb.append(EventSessionSchema.ED_ID);
sb.append(" = ed.");
sb.append(EventDeviceSchema._ID);
sb.append(join);
sb.append(ClientSchema.TABLE_NAME);
sb.append(" as c ON es.");
sb.append(EventSessionSchema.C_ID);
sb.append(" = c.");
sb.append(ClientSchema._ID);
sb.append(" WHERE p.");
sb.append(ProfileSchema.NAME);
sb.append(prepared);
sb.append(and);
sb.append("i.");
sb.append(InterfaceSchema.NAME);
sb.append(prepared);
sb.append(and);
sb.append("a.");
sb.append(AttributeSchema.NAME);
sb.append(prepared);
sb.append(and);
sb.append("d.");
sb.append(DeviceSchema.SERVICE_ID);
sb.append(prepared);
sb.append(and);
sb.append("c.");
sb.append(ClientSchema.ORIGIN);
sb.append(prepared);
sb.append(and);
sb.append("c.");
sb.append(ClientSchema.RECEIVER);
sb.append(prepared);
String inter = null2WhiteSpace(event.getInterface());
String attr = null2WhiteSpace(event.getAttribute());
String serviceId = null2WhiteSpace(event.getServiceId());
String receiver = null2WhiteSpace(event.getReceiverName());
String[] params = {event.getProfile(), inter, attr,
serviceId, event.getOrigin(), receiver};
Cursor c = db.rawQuery(sb.toString(), params);
if (c.moveToFirst()) {
result = new EventSession();
if (c.getColumnIndex(_ID) != -1) {
result.mId = c.getLong(0);
result.mEdId = c.getLong(1);
result.mCId = c.getLong(2);
long createTime = c.getLong(3);
long updateTime = c.getLong(4);
result.mCreateDate = new Timestamp(createTime);
result.mUpdateDate = new Timestamp(updateTime);
}
}
c.close();
return result;
}
static List<Event> getEventsByCid(final SQLiteDatabase db, final long cid) {
List<Event> result = new ArrayList<>();
StringBuilder sb = new StringBuilder();
String join = " INNER JOIN ";
String prepared = " = ? ";
sb.append("SELECT ");
sb.append("a.");
sb.append(AttributeSchema.NAME);
sb.append(", i.");
sb.append(InterfaceSchema.NAME);
sb.append(", p.");
sb.append(ProfileSchema.NAME);
sb.append(", d.");
sb.append(DeviceSchema.SERVICE_ID);
sb.append(" FROM ");
sb.append(ProfileSchema.TABLE_NAME);
sb.append(" as p");
sb.append(join);
sb.append(InterfaceSchema.TABLE_NAME);
sb.append(" as i ON p.");
sb.append(ProfileSchema._ID);
sb.append(" = i.");
sb.append(InterfaceSchema.P_ID);
sb.append(join);
sb.append(AttributeSchema.TABLE_NAME);
sb.append(" as a ON i.");
sb.append(InterfaceSchema._ID);
sb.append(" = a.");
sb.append(AttributeSchema.I_ID);
sb.append(join);
sb.append(EventDeviceSchema.TABLE_NAME);
sb.append(" as ed ON a.");
sb.append(AttributeSchema._ID);
sb.append(" = ed.");
sb.append(EventDeviceSchema.A_ID);
sb.append(join);
sb.append(DeviceSchema.TABLE_NAME);
sb.append(" as d ON ed.");
sb.append(EventDeviceSchema.D_ID);
sb.append(" = d.");
sb.append(DeviceSchema._ID);
sb.append(join);
sb.append(EventSessionSchema.TABLE_NAME);
sb.append(" as es ON es.");
sb.append(EventSessionSchema.ED_ID);
sb.append(" = ed.");
sb.append(EventDeviceSchema._ID);
sb.append(join);
sb.append(ClientSchema.TABLE_NAME);
sb.append(" as c ON es.");
sb.append(EventSessionSchema.C_ID);
sb.append(" = c.");
sb.append(ClientSchema._ID);
sb.append(" WHERE es.");
sb.append(EventSessionSchema.C_ID);
sb.append(prepared);
String[] params = { "" + cid };
Cursor c = db.rawQuery(sb.toString(), params);
if (c.moveToFirst()) {
do {
Event event = new Event();
event.setAttribute(c.getString(0));
event.setInterface(c.getString(1));
event.setProfile(c.getString(2));
event.setServiceId(c.getString(3));
result.add(event);
} while (c.moveToNext());
}
c.close();
return result;
}
/**
* 文字列がnullの場合空文字を返す.
*
* @param str 解析対象文字列
* @return nullの場合空文字、その他は引数の文字列をそのまま返す。
*/
private static String null2WhiteSpace(final String str) {
return (str == null) ? "" : str;
}
}