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