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        public void addItems(SQLItem item) {
040            SQLItem[] tmp=new SQLItem[items.length+1];
041            for(int i=0;i<items.length;i++) {
042                    tmp[i]=items[i];
043            }
044            tmp[items.length]=item;
045            items=tmp;
046        }
047        
048        @Override
049        public SQLItem[] getItems() {
050            return items;
051        }
052    
053        @Override
054        public int getPosition() {
055            return position;
056        }
057        
058        @Override
059        public void setPosition(int position) {
060            this.position = position;
061        }    
062        
063    
064        @Override
065        public String getSQLString() {
066            return strSQL;
067        }
068        
069        @Override
070        public void setSQLString(String strSQL) {
071            this.strSQL= strSQL;
072        }
073    
074        @Override
075        public String toString() {
076            if(items.length==0) return strSQL;
077            StringBuffer sb=new StringBuffer();
078            int pos;
079            int last=0;
080            for(int i=0;i<items.length;i++) {
081                pos=strSQL.indexOf('?',last);
082                if(pos==-1) {
083                    sb.append(strSQL.substring(last));
084                    break;
085                }
086                sb.append(strSQL.substring(last,pos));
087                if(items[i].isNulls()) sb.append("null");
088                else sb.append(SQLCaster.toString(items[i]));
089                last=pos+1;
090            }
091            sb.append(strSQL.substring(last));
092            return sb.toString();
093        }    
094        
095        @Override
096        public String toHashString() {
097            if(items.length==0) return strSQL;
098            StringBuffer sb=new StringBuffer(strSQL);
099            for(int i=0;i<items.length;i++) {
100                sb.append(';').append(items[i].toString());
101            }
102            return sb.toString();
103        }
104    
105            public long sizeOf() {
106                    return SizeOf.size(strSQL)+SizeOf.size(position)+SizeOf.size(items);
107            }
108    
109            public static SQL duplicate(SQL sql) {
110                    if(!(sql instanceof SQLImpl)) return sql;
111                    return ((SQLImpl) sql).duplicate();
112            }
113    
114            public SQL duplicate() {
115                    SQLImpl rtn=new SQLImpl(strSQL);
116                    rtn.position=position;
117                    rtn.items=new SQLItem[items.length];
118                    for(int i=0;i<items.length;i++){
119                            rtn.items[i]=SQLItemImpl.duplicate(items[i]);
120                    }
121                    
122                    return rtn;
123            }
124    
125    }