001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019/**
020 * Implements the CFML Function arraymin
021 */
022package lucee.runtime.functions.query;
023
024import lucee.runtime.PageContext;
025import lucee.runtime.exp.FunctionException;
026import lucee.runtime.exp.PageException;
027import lucee.runtime.functions.BIF;
028import lucee.runtime.op.Caster;
029import lucee.runtime.type.Collection;
030import lucee.runtime.type.Query;
031import lucee.runtime.type.QueryImpl;
032
033public final class QuerySlice extends BIF {
034
035        private static final long serialVersionUID = -2760070317171532995L;
036
037        public static Query call(PageContext pc , Query qry,double offset) throws PageException {
038                return call(pc , qry, offset,0);
039        }
040        public static Query call(PageContext pc , Query qry,double offset,double length) throws PageException {
041                        
042                int len=qry.getRecordcount();
043                if(offset>0) {
044                        if(len<offset)throw new FunctionException(pc,"querySlice",2,"offset","offset can be greater than recordcount of the query");
045                        
046                        int to=0;
047                        if(length>0)to=(int)(offset+length-1);
048                        else if(length<=0)to=(int)(len+length);
049                        if(len<to)
050                                throw new FunctionException(pc,"querySlice",3,"length","offset+length can be greater than recordcount of the query");
051                        
052                        return get(qry,(int)offset,to);
053                }
054                return call(pc ,qry,len+offset,length);
055        }
056        
057        @Override
058        public Object invoke(PageContext pc, Object[] args) throws PageException {
059                if(args.length==2)return call(pc,Caster.toQuery(args[0]),Caster.toDoubleValue(args[1]));
060                return call(pc,Caster.toQuery(args[0]),Caster.toDoubleValue(args[1]),Caster.toDoubleValue(args[2]));
061        }
062
063        private static Query get(Query qry, int from, int to) throws PageException {
064                Collection.Key[] columns;
065                //print.out(from+"::"+to);
066                Query nq=new QueryImpl(columns=qry.getColumnNames(),0,qry.getName());
067                
068                int row=1;
069                for(int i=from;i<=to;i++) {nq.addRow();
070                        for(int y=0;y<columns.length;y++) {
071                                nq.setAt(columns[y], row, qry.getAt(columns[y], i));
072                        }
073                        row++;
074                }
075                return nq;
076        }
077        
078
079}