package eu.ttbox.androgister.domain.dao.order; import java.util.ArrayList; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.util.Log; import eu.ttbox.androgister.AndroGisterApplication; import eu.ttbox.androgister.domain.Order; import eu.ttbox.androgister.domain.OrderDao; import eu.ttbox.androgister.domain.OrderItem; import eu.ttbox.androgister.domain.OrderItemDao; import eu.ttbox.androgister.domain.dao.helper.OrderHelper; import eu.ttbox.androgister.domain.ref.OrderStatusEnum; public class OrderDatabase { private static final String TAG = "OrderItemDatabase"; private static final String ORDER_WHERE_SELECT_BY_ID = String.format("%s = ?", OrderDao.Properties.Id.columnName); // Dao private OrderDao orderDao; private OrderItemDao orderItemDao; // Id Generator private OrderIdGenerator orderIdGenerator; // Concurency Lock private Object[] lockInsertOrder = new Object[0]; /** * Constructor * * @param context * The Context within which to work, used to create the DB */ public OrderDatabase(Context context) { // Init Dao AndroGisterApplication app = (AndroGisterApplication) context.getApplicationContext(); orderDao = app.getDaoSession().getOrderDao(); orderItemDao = app.getDaoSession().getOrderItemDao(); // Generator orderIdGenerator = new OrderIdGenerator(context); } public SQLiteDatabase getWritableDatabase() { return orderDao.getDatabase(); } public long insertOrder(String deviceId, Order order, ArrayList<OrderItem> orderItems) throws SQLException { long result = -1; synchronized (lockInsertOrder) { SQLiteDatabase db = orderDao.getDatabase(); try { try { db.beginTransaction(); result = insertOrder(deviceId, order, orderItems, db); // Commit db.setTransactionSuccessful(); } finally { db.endTransaction(); } } finally { // db.close(); } } return result; } private Order getOrderModel(SQLiteDatabase db, String orderId) { Order order = null; SQLiteQueryBuilder builder = new SQLiteQueryBuilder(); builder.setTables(OrderDao.TABLENAME); Cursor cursorOrder = builder.query(db, orderDao.getAllColumns(), ORDER_WHERE_SELECT_BY_ID, new String[] { orderId }, null, null, null); try { // Validate Query if (cursorOrder.getCount() != 1) { throw new RuntimeException("Not unique result for Order with id " + orderId); } // Read Cursor cursorOrder.moveToFirst(); OrderHelper helper = new OrderHelper(); order = orderDao.readEntity(cursorOrder, 0); } finally { cursorOrder.close(); } return order; } private long insertOrder(String deviceId, Order order, ArrayList<OrderItem> items, SQLiteDatabase db) throws SQLException { long result = -1; try { // TODO Check for increment number long now = System.currentTimeMillis(); order.setOrderDate(now); // Order Id long orderNumberNum = orderIdGenerator.getNextOrderNum(db, now); order.setOrderNumber(orderNumberNum); if (order.getStatus() == null) { order.setStatus(OrderStatusEnum.ORDER); } // Order UUID String orderUUID = OrderHelper.generateOrderUUID(now, deviceId, orderNumberNum); order.setOrderUUID(orderUUID); Log.d(TAG, "Compute new Order UUID : " + orderUUID); // Order ContentValues orderValues = orderDao.readContentValues(order); long orderId = db.insertOrThrow(OrderDao.TABLENAME, null, orderValues); order.setId(orderId); // Orders Items if (items != null && !items.isEmpty()) { for (OrderItem item : items) { item.setOrderId(orderId); ContentValues itemValues = orderItemDao.readContentValues(item); long itemId = db.insertOrThrow(OrderItemDao.TABLENAME, null, itemValues); item.setId(itemId); } } result = orderId; } catch (SQLException e) { orderIdGenerator.invalidateCacheCounter(); Log.w(TAG, "invalidate orderIdGenerator Cache Counter for SQLException : " + e.getMessage()); throw e; } catch (RuntimeException er) { orderIdGenerator.invalidateCacheCounter(); Log.w(TAG, "invalidate orderIdGenerator Cache Counter for RuntimeException : " + er.getMessage()); throw er; } return result; } public long deleteOrder(String deviceId, long orderId) throws SQLException { long result = -1; synchronized (lockInsertOrder) { SQLiteDatabase db = orderDao.getDatabase(); try { try { db.beginTransaction(); // Get A order clone String orderIdAsString = String.valueOf(orderId); Order order = getOrderModel(db, orderIdAsString); // Validate Order Delete Possible boolean isPossible = OrderHelper.isOrderDeletePossible(order); if (!isPossible) { return -1; } // TODO Manage flag Order orderInv = new Order(order); // Revert Order orderInv.setId(null); orderInv.setStatus(OrderStatusEnum.ORDER_CANCEL); orderInv.resetItems(); orderInv.setOrderDeleteUUID(order.getOrderUUID()); orderInv.setOrderUUID(null); orderInv.setOrderNumber(-1); orderInv.setPriceSumHT(-1 * orderInv.getPriceSumHT()); // Insert New Clone result = insertOrder(deviceId, orderInv, null, db); if (result == -1) { throw new RuntimeException(String.format("Could not insert Inversed Order for Original Order Id %s", orderId)); } // Update Order fot Cancel status ContentValues values = new ContentValues(); values.put(OrderDao.Properties.OrderDeleteUUID.columnName, orderInv.getOrderUUID()); int updatedRow = db.update(OrderDao.TABLENAME, values, ORDER_WHERE_SELECT_BY_ID, new String[] { orderIdAsString }); if (updatedRow != 1) { throw new RuntimeException(String.format("Wrong number of update %s line for Order Id %s", updatedRow, orderId)); } // Commit db.setTransactionSuccessful(); } finally { db.endTransaction(); } } finally { // db.close(); } } return result; } }