/** * Counts all entities of the specified type matching the given {@link Query} instance. The SQL * runs as a <code>SELECT COUNT(*)</code> to ensure maximum performance. * * @param type The type of the entities which should be counted. * @param query The {@link Query} instance used to determine the result set which will be counted. * @return The number of entities of the given type which match the specified query. */ public <K> int count(Class<? extends RawEntity<K>> type, Query query) throws SQLException { int back = -1; Connection conn = getProvider().getConnection(); try { String sql = null; tableNameConverterLock.readLock().lock(); try { sql = query.toSQL(type, provider, tableNameConverter, getFieldNameConverter(), true); } finally { tableNameConverterLock.readLock().unlock(); } Logger.getLogger("net.java.ao").log(Level.INFO, sql); PreparedStatement stmt = conn.prepareStatement(sql); provider.setQueryStatementProperties(stmt, query); query.setParameters(this, stmt); ResultSet res = stmt.executeQuery(); if (res.next()) { back = res.getInt(1); } res.close(); stmt.close(); } finally { conn.close(); } return back; }
public boolean checkIfFavorite(String listingID) { String queryf = "select * from " + FavoriteParkingSchema.TABLE_NAME + " where " + FavoriteParkingSchema.LISTING_ID + "='" + listingID + "'"; return mProvider.itemExists(queryf); }
public void addFavorite(GarageModel garageModel) { if (!Utils.isStringEmpty(garageModel.getListingID())) { FavoriteParking favorite = new FavoriteParking(); favorite.listingID = garageModel.getListingID(); favorite.listingName = garageModel.getName(); favorite.listingAddress = garageModel.getAddress(); favorite.listingCity = garageModel.getCity(); favorite.listingState = garageModel.getState(); favorite.listingZip = garageModel.getZip(); favorite.latitude = Double.toString(garageModel.getLatitude()); favorite.longitude = Double.toString(garageModel.getLongitude()); favorite.price = Integer.toString(garageModel.getPrice()); mProvider.create(favorite); } }
public ArrayList<GarageModel> getAllFavorites() { try { List<FavoriteParking> favoriteList = mProvider.getAll(FavoriteParking.class); if (!Utils.checkIfNull(favoriteList)) { ArrayList<GarageModel> garageModels = new ArrayList<>(); for (FavoriteParking fp : favoriteList) { garageModels.add(favToPlace(fp)); } return garageModels; } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; }
/** * Selects all entities of the specified type which match the given <code>Query</code>. This * method creates a <code>PreparedStatement</code> using the <code>Query</code> instance specified * against the table represented by the given type. This query is then executed (with the * parameters specified in the query). The method then iterates through the result set and * extracts the specified field, mapping an entity of the given type to each row. This array of * entities is returned. * * @param type The type of the entities to retrieve. * @param field The field value to use in the creation of the entities. This is usually the * primary key field of the corresponding table. * @param query The {@link Query} instance to use in determining the results. * @return An array of entities of the given type which match the specified query. */ public <T extends RawEntity<K>, K> T[] find(Class<T> type, String field, Query query) throws SQLException { List<T> back = new ArrayList<T>(); query.resolveFields(type, getFieldNameConverter()); // <ian> Version version = type.getAnnotation(Version.class); if (version != null && !version.findInitial()) { // Add initial version check to exclude // objects that have only been created and not saved yet. if (query.getWhereClause() == null) { query.where(version.value() + " != ?", version.initial()); } else { // Preserve existing WHERE clause and parameters String whereClause = new StringBuilder() .append(query.getWhereClause()) .append(" AND ") .append(version.value()) .append(" != ?") .toString(); Object[] paramsOld = query.getWhereParams(); Object[] paramsNew = new Object[paramsOld.length + 1]; System.arraycopy(paramsOld, 0, paramsNew, 0, paramsOld.length); paramsNew[paramsNew.length - 1] = version.initial(); query.setWhereClause(whereClause); query.setWhereParams(paramsNew); } } // </ian> Preload preloadAnnotation = type.getAnnotation(Preload.class); if (preloadAnnotation != null) { if (!query.getFields()[0].equals("*") && query.getJoins().isEmpty()) { String[] oldFields = query.getFields(); List<String> newFields = new ArrayList<String>(); for (String newField : preloadAnnotation.value()) { newField = newField.trim(); int fieldLoc = -1; for (int i = 0; i < oldFields.length; i++) { if (oldFields[i].equals(newField)) { fieldLoc = i; break; } } if (fieldLoc < 0) { newFields.add(newField); } else { newFields.add(oldFields[fieldLoc]); } } if (!newFields.contains("*")) { for (String oldField : oldFields) { if (!newFields.contains(oldField)) { newFields.add(oldField); } } } query.setFields(newFields.toArray(new String[newFields.size()])); } } Connection conn = getProvider().getConnection(); try { String sql = null; tableNameConverterLock.readLock().lock(); try { sql = query.toSQL(type, provider, tableNameConverter, getFieldNameConverter(), false); } finally { tableNameConverterLock.readLock().unlock(); } Logger.getLogger("net.java.ao").log(Level.INFO, sql); PreparedStatement stmt = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); provider.setQueryStatementProperties(stmt, query); query.setParameters(this, stmt); ResultSet res = stmt.executeQuery(); provider.setQueryResultSetProperties(res, query); while (res.next()) { T entity = peer( type, Common.getPrimaryKeyType(type) .pullFromDatabase(this, res, Common.getPrimaryKeyClassType(type), field)); CacheLayer cacheLayer = getProxyForEntity(entity).getCacheLayer(entity); for (String cacheField : query.getCanonicalFields(type, fieldNameConverter)) { cacheLayer.put(cacheField, res.getObject(cacheField)); } back.add(entity); } res.close(); stmt.close(); } finally { conn.close(); } return back.toArray((T[]) Array.newInstance(type, back.size())); }
/** * Deletes the specified entities from the database. DELETE statements are called on the rows in * the corresponding tables and the entities are removed from the instance cache. The entity * instances themselves are not invalidated, but it doesn't even make sense to continue using the * instance without a row with which it is paired. * * <p>This method does attempt to group the DELETE statements on a per-type basis. Thus, if you * pass 5 instances of <code>EntityA</code> and two instances of <code>EntityB</code>, the * following SQL prepared statements will be invoked: * * <pre>DELETE FROM entityA WHERE id IN (?,?,?,?,?); * DELETE FROM entityB WHERE id IN (?,?);</pre> * * <p>Thus, this method scales very well for large numbers of entities grouped into types. * However, the execution time increases linearly for each entity of unique type. * * @param entities A varargs array of entities to delete. Method returns immediately if length == * 0. */ @SuppressWarnings("unchecked") public void delete(RawEntity<?>... entities) throws SQLException { if (entities.length == 0) { return; } Map<Class<? extends RawEntity<?>>, List<RawEntity<?>>> organizedEntities = new HashMap<Class<? extends RawEntity<?>>, List<RawEntity<?>>>(); for (RawEntity<?> entity : entities) { verify(entity); Class<? extends RawEntity<?>> type = getProxyForEntity(entity).getType(); if (!organizedEntities.containsKey(type)) { organizedEntities.put(type, new LinkedList<RawEntity<?>>()); } organizedEntities.get(type).add(entity); } entityCacheLock.writeLock().lock(); try { DatabaseProvider provider = getProvider(); Connection conn = provider.getConnection(); try { for (Class<? extends RawEntity<?>> type : organizedEntities.keySet()) { List<RawEntity<?>> entityList = organizedEntities.get(type); StringBuilder sql = new StringBuilder("DELETE FROM "); tableNameConverterLock.readLock().lock(); try { sql.append(provider.processID(tableNameConverter.getName(type))); } finally { tableNameConverterLock.readLock().unlock(); } sql.append(" WHERE ") .append(provider.processID(Common.getPrimaryKeyField(type, getFieldNameConverter()))) .append(" IN (?"); for (int i = 1; i < entityList.size(); i++) { sql.append(",?"); } sql.append(')'); Logger.getLogger("net.java.ao").log(Level.INFO, sql.toString()); PreparedStatement stmt = conn.prepareStatement(sql.toString()); int index = 1; for (RawEntity<?> entity : entityList) { TypeManager.getInstance() .getType((Class) entity.getEntityType()) .putToDatabase(this, stmt, index++, entity); } relationsCache.remove(type); stmt.executeUpdate(); stmt.close(); } } finally { conn.close(); } for (RawEntity<?> entity : entities) { entityCache.remove(new CacheKey(Common.getPrimaryKeyValue(entity), entity.getEntityType())); } proxyLock.writeLock().lock(); try { for (RawEntity<?> entity : entities) { proxies.remove(entity); } } finally { proxyLock.writeLock().unlock(); } } finally { entityCacheLock.writeLock().unlock(); } }
/** * Creates a new entity of the specified type with the optionally specified initial parameters. * This method actually inserts a row into the table represented by the entity type and returns * the entity instance which corresponds to that row. * * <p>The {@link DBParam} object parameters are designed to allow the creation of entities which * have non-null fields which have no defalut or auto-generated value. Insertion of a row without * such field values would of course fail, thus the need for db params. The db params can also be * used to set the values for any field in the row, leading to more compact code under certain * circumstances. * * <p>Unless within a transaction, this method will commit to the database immediately and exactly * once per call. Thus, care should be taken in the creation of large numbers of entities. There * doesn't seem to be a more efficient way to create large numbers of entities, however one should * still be aware of the performance implications. * * <p>This method delegates the action INSERT action to {@link * DatabaseProvider#insertReturningKey(EntityManager, Connection, Class, String, boolean, String, * DBParam...)}. This is necessary because not all databases support the JDBC <code> * RETURN_GENERATED_KEYS</code> constant (e.g. PostgreSQL and HSQLDB). Thus, the database provider * itself is responsible for handling INSERTion and retrieval of the correct primary key value. * * @param type The type of the entity to INSERT. * @param params An optional varargs array of initial values for the fields in the row. These * values will be passed to the database within the INSERT statement. * @return The new entity instance corresponding to the INSERTed row. * @see net.java.ao.DBParam * @see net.java.ao.DatabaseProvider#insertReturningKey(EntityManager, Connection, Class, String, * boolean, String, DBParam...) */ public <T extends RawEntity<K>, K> T create(Class<T> type, DBParam... params) throws SQLException { T back = null; String table = null; tableNameConverterLock.readLock().lock(); try { table = tableNameConverter.getName(type); } finally { tableNameConverterLock.readLock().unlock(); } Set<DBParam> listParams = new HashSet<DBParam>(); listParams.addAll(Arrays.asList(params)); fieldNameConverterLock.readLock().lock(); try { for (Method method : MethodFinder.getInstance().findAnnotation(Generator.class, type)) { Generator genAnno = method.getAnnotation(Generator.class); String field = fieldNameConverter.getName(method); ValueGenerator<?> generator; valGenCacheLock.writeLock().lock(); try { if (valGenCache.containsKey(genAnno.value())) { generator = valGenCache.get(genAnno.value()); } else { generator = genAnno.value().newInstance(); valGenCache.put(genAnno.value(), generator); } } catch (InstantiationException e) { continue; } catch (IllegalAccessException e) { continue; } finally { valGenCacheLock.writeLock().unlock(); } listParams.add(new DBParam(field, generator.generateValue(this))); } // <ian> Version version = type.getAnnotation(Version.class); if (version != null) { // Initialize version upon creation. String field = version.value(); int initial = version.initial(); listParams.add(new DBParam(field, initial)); } // </ian> } finally { fieldNameConverterLock.readLock().unlock(); } Connection conn = getProvider().getConnection(); try { Method pkMethod = Common.getPrimaryKeyMethod(type); back = peer( type, provider.insertReturningKey( this, conn, Common.getPrimaryKeyClassType(type), Common.getPrimaryKeyField(type, getFieldNameConverter()), pkMethod.getAnnotation(AutoIncrement.class) != null, table, listParams.toArray(new DBParam[listParams.size()]))); } finally { conn.close(); } relationsCache.remove(type); back.init(); return back; }
/** * Creates a new instance of <code>EntityManager</code> by auto-magically finding a {@link * DatabaseProvider} instance for the specified JDBC URI, username and password. The * auto-magically determined instance is pooled by default (if a supported connection pooling * library is available on the classpath). * * <p>The actual auto-magical parsing code isn't contained within this method, but in {@link * DatabaseProvider#getInstance(String, String, String)}. This way, it is possible to use the * parsing logic to get a <code>DatabaseProvider</code> instance separate from <code>EntityManager * </code> if necessary. * * @param uri The JDBC URI to use for the database connection. * @param username The username to use in authenticating the database connection. * @param password The password to use in authenticating the database connection. * @see #EntityManager(DatabaseProvider) * @see net.java.ao.DatabaseProvider#getInstance(String, String, String) */ public EntityManager(String uri, String username, String password) { this(DatabaseProvider.getInstance(uri, username, password)); }
public void deleteAllFavorites() { mProvider.deleteAllData(FavoriteParkingSchema.TABLE_NAME); }
public void deleteFavorite(GarageModel garageModel) { mProvider.delete( FavoriteParkingSchema.TABLE_NAME, FavoriteParkingSchema.LISTING_ID + " = ?", new String[] {garageModel.getListingID()}); }
public FavoriteParkingProvider(Context context) { mContext = context; mProvider = DatabaseProvider.getInstance(mContext); }