/** * This method will return a list of records for a specific page. * * @param pageNumber page number to return. This is indexed at 1, not 0. Any value below 1 is illegal and will * be rejected. * @return list of records that match a query make up a "page". */ public LazyList<T> getPage(int pageNumber) { if (pageNumber < 1) throw new IllegalArgumentException("minimum page index == 1"); try { LazyList<T> list = find(query, params).offset((pageNumber - 1) * pageSize).limit(pageSize); if (orderBys != null) { list.orderBy(orderBys); } currentPageIndex = pageNumber; return list; } catch (Exception mustNeverHappen) { throw new InternalException(mustNeverHappen); } }
private void processParent(BelongsToAssociation association) { if (delegate.isEmpty()) { // no need to process parents if no models selected. return; } //need to remove duplicates because more than one child can belong to the same parent. Set<Object> distinctParentIds = collectDistinct(association.getFkName()); distinctParentIds.remove(null); // remove null parent id if (distinctParentIds.isEmpty()) { return; } final MetaModel parentMetaModel = metaModelOf(association.getTargetClass()); final Map<Object, Model> parentById = new HashMap<>(); StringBuilder query = new StringBuilder().append(parentMetaModel.getIdName()).append(" IN ("); appendQuestions(query, distinctParentIds.size()); query.append(')'); for (Model parent : new LazyList<>(query.toString(), parentMetaModel, distinctParentIds.toArray())) { parentById.put(parent.getId(), parent); } //now that we have the parents in the has, we need to distribute them into list of children that are //stored in the delegate. for (Model child : delegate) { // parent could be null, which is fine child.setCachedParent(parentById.get(child.get(association.getFkName()))); } }
/** * This method exists to force immediate load from DB. Example; * <code> Person.find("name = ?", "Smith").load();</code>. * It is not possible to call other methods after load(). The load() method should be the last to be called in the chain: * <code> Person.find("name = ?", "Smith").limit(10).load();</code>. * This: will generate exception: <code> Person.find("name = ?", "Smith").load().limit();</code>. * * @return fully loaded list. */ //TODO: write test, and also test for exception. public <E extends Model> LazyList<E> load() { if (hydrated()) { throw new DBException("load() must be the last on the chain of methods"); } hydrate(); return (LazyList<E>) this; }
private void processPolymorphicChildren(OneToManyPolymorphicAssociation association) { if (delegate.isEmpty()) {//no need to process children if no models selected. return; } MetaModel childMetaModel = metaModelOf(association.getTargetClass()); Map<Object, List<Model>> childrenByParentId = new HashMap<>(); List<Object> ids = collect(metaModel.getIdName()); StringBuilder query = new StringBuilder().append("parent_id IN ("); appendQuestions(query, ids.size()); query.append(") AND parent_type = '").append(association.getTypeLabel()).append('\''); for (Model child : new LazyList<>(query.toString(), childMetaModel, ids.toArray()).orderBy(childMetaModel.getIdName())) { if (childrenByParentId.get(child.get("parent_id")) == null) { childrenByParentId.put(child.get("parent_id"), new SuperLazyList<>()); } childrenByParentId.get(child.get("parent_id")).add(child); } for (T parent : delegate) { List<Model> children = childrenByParentId.get(parent.getId()); if (children != null) { parent.setChildren(childMetaModel.getModelClass(), children); } else { parent.setChildren(childMetaModel.getModelClass(), new SuperLazyList<>()); } } }
@Override protected void hydrate() { if (hydrated()) { return; } String sql= toSql(false); if(metaModel.cached()){ List<T> cached = (List<T>) QueryCache.instance().getItem(metaModel.getTableName(), sql, params); if(cached != null){ delegate = cached; LogFilter.logQuery(LOGGER, sql, params, System.currentTimeMillis(), true); return; } } delegate = new ArrayList<>(); long start = System.currentTimeMillis(); new DB(metaModel.getDbName()).find(sql, params).with(new RowListenerAdapter() { @Override public void onNext(Map<String, Object> map) { delegate.add(ModelDelegate.<T>instance(map, metaModel)); } }); LogFilter.logQuery(LOGGER, sql, params, start, false); if(metaModel.cached()){ delegate = Collections.unmodifiableList(delegate); QueryCache.instance().addItem(metaModel.getTableName(), sql, params, delegate); } processIncludes(); }
private void collect(Collection results, String attributeName) { hydrate(); for (Model model : delegate) { results.add(model.get(attributeName)); } }
private LazyList<T> findAll() { return new LazyList<>(null, metaModel); }
public List collect(String attributeName, String filterAttribute, Object filterValue) { List results = new ArrayList(); collect(results, attributeName, filterAttribute, filterValue); return results; }
/** * Dumps contents of this list to <code>System.out</code>. */ public void dump(){ dump(System.out); }
private void processChildren(OneToManyAssociation association) { if(delegate.isEmpty()){//no need to process children if no models selected. return; } final MetaModel childMetaModel = metaModelOf(association.getTargetClass()); final String fkName = association.getFkName(); final Map<Object, List<Model>> childrenByParentId = new HashMap<>(); List<Object> ids = collect(metaModel.getIdName()); StringBuilder query = new StringBuilder().append(fkName).append(" IN ("); appendQuestions(query, ids.size()); query.append(')'); for (Model child : new LazyList<>(query.toString(), childMetaModel, ids.toArray()).orderBy(childMetaModel.getIdName())) { if(childrenByParentId.get(child.get(fkName)) == null){ childrenByParentId.put(child.get(fkName), new SuperLazyList<>()); } childrenByParentId.get(child.get(fkName)).add(child); } for(T parent : delegate){ List<Model> children = childrenByParentId.get(parent.getId()); if(children != null){ parent.setChildren(childMetaModel.getModelClass(), children); } else { parent.setChildren(childMetaModel.getModelClass(), new SuperLazyList<>()); } } }
@Override protected void hydrate() { if (hydrated()) { return; } String sql= toSql(false); if(metaModel.cached()){ List<T> cached = (List<T>) QueryCache.instance().getItem(metaModel.getTableName(), sql, params); if(cached != null){ delegate = cached; return; } } delegate = new ArrayList<T>(); long start = System.currentTimeMillis(); new DB(metaModel.getDbName()).find(sql, params).with(new RowListenerAdapter() { @Override public void onNext(Map<String, Object> map) { delegate.add(ModelDelegate.<T>instance(map, metaModel)); } }); LogFilter.logQuery(logger, sql, params, start); if(metaModel.cached()){ delegate = Collections.unmodifiableList(delegate); QueryCache.instance().addItem(metaModel.getTableName(), sql, params, delegate); } processIncludes(); }
/** * Dumps content of list to a stream. Use for debugging. * @param out */ public void dump(OutputStream out){ hydrate(); PrintWriter p = new PrintWriter(out); for(Model m : delegate){ p.write(m.toString()); p.write('\n'); } p.flush(); }
private LazyList<T> find(String query, Object... params) { if (query.equals("*")) { if (params.length == 0) { return findAll(); } else { throw new IllegalArgumentException("cannot provide parameters with query: '*'"); } } return fullQuery ? new LazyList<T>(true, metaModel, this.query, params) : new LazyList<T>(query, metaModel, params); }
public Set collectDistinct(String attributeName) { Set results = new LinkedHashSet(); collect(results, attributeName); return results; }
/** * This method exists to force immediate load from DB. Example; * <code> Person.find("name = ?", "Smith").load();</code>. * It is not possible to call other methods after load(). The load() method should be the last to be called in the chain: * <code> Person.find("name = ?", "Smith").limit(10).load();</code>. * This: will generate exception: <code> Person.find("name = ?", "Smith").load().limit();</code>. * * @return fully loaded list. */ //TODO: write test, and also test for exception. public <E extends Model> LazyList<E> load() { if (hydrated()) { throw new DBException("load() must be the last on the chain of methods"); } hydrate(); return (LazyList<E>) this; }
/** * Dumps contents of this list to <code>System.out</code>. */ public void dump(){ dump(System.out); }