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 **/
019package lucee.runtime.db;
020
021import java.io.Serializable;
022
023import lucee.commons.lang.SizeOf;
024import lucee.runtime.type.Sizeable;
025
026
027
028
029/**
030 * represents a SQL Statement with his defined arguments for a prepared statement
031 */
032public final class SQLImpl implements SQL,Serializable,Sizeable {
033    
034    private String strSQL;
035    private SQLItem[] items;
036    private int position=0;
037
038    /**
039     * Constructor only with SQL String
040     * @param strSQL SQL String
041     */
042    public SQLImpl(String strSQL) {
043        this.strSQL=strSQL;
044        this.items=new SQLItem[0];
045    }
046    
047    /**
048     * Constructor with SQL String and SQL Items
049     * @param strSQL SQL String
050     * @param items SQL Items
051     */
052    public SQLImpl(String strSQL, SQLItem[] items) {
053        this.strSQL=strSQL;
054        this.items=items;
055    }
056    
057    public void addItems(SQLItem item) {
058        SQLItem[] tmp=new SQLItem[items.length+1];
059        for(int i=0;i<items.length;i++) {
060                tmp[i]=items[i];
061        }
062        tmp[items.length]=item;
063        items=tmp;
064    }
065    
066    @Override
067    public SQLItem[] getItems() {
068        return items;
069    }
070
071    @Override
072    public int getPosition() {
073        return position;
074    }
075    
076    @Override
077    public void setPosition(int position) {
078        this.position = position;
079    }    
080    
081
082    @Override
083    public String getSQLString() {
084        return strSQL;
085    }
086    
087    @Override
088    public void setSQLString(String strSQL) {
089        this.strSQL= strSQL;
090    }
091
092    @Override
093    public String toString() {
094        if(items.length==0) return strSQL;
095        StringBuilder sb=new StringBuilder();
096        int pos;
097        int last=0;
098        for(int i=0;i<items.length;i++) {
099            pos=strSQL.indexOf('?',last);
100            if(pos==-1) {
101                sb.append(strSQL.substring(last));
102                break;
103            }
104            sb.append(strSQL.substring(last,pos));
105            if(items[i].isNulls()) sb.append("null");
106            else sb.append(SQLCaster.toString(items[i]));
107            last=pos+1;
108        }
109        sb.append(strSQL.substring(last));
110        return sb.toString();
111    }    
112    
113    @Override
114    public String toHashString() {
115        if(items.length==0) return strSQL;
116        StringBuilder sb=new StringBuilder(strSQL);
117        for(int i=0;i<items.length;i++) {
118            sb.append(';').append(items[i].toString());
119        }
120        return sb.toString();
121    }
122
123        public long sizeOf() {
124                return SizeOf.size(strSQL)+SizeOf.size(position)+SizeOf.size(items);
125        }
126
127        public static SQL duplicate(SQL sql) {
128                if(!(sql instanceof SQLImpl)) return sql;
129                return ((SQLImpl) sql).duplicate();
130        }
131
132        public SQL duplicate() {
133                SQLImpl rtn=new SQLImpl(strSQL);
134                rtn.position=position;
135                rtn.items=new SQLItem[items.length];
136                for(int i=0;i<items.length;i++){
137                        rtn.items[i]=SQLItemImpl.duplicate(items[i]);
138                }
139                
140                return rtn;
141        }
142
143}