001    /**
002     * Copyright (c) 2010 Yahoo! Inc. All rights reserved.
003     * Licensed under the Apache License, Version 2.0 (the "License");
004     * you may not use this file except in compliance with the License.
005     * You may obtain a copy of the License at
006     *
007     *   http://www.apache.org/licenses/LICENSE-2.0
008     *
009     *  Unless required by applicable law or agreed to in writing, software
010     *  distributed under the License is distributed on an "AS IS" BASIS,
011     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012     *  See the License for the specific language governing permissions and
013     *  limitations under the License. See accompanying LICENSE file.
014     */
015    package org.apache.oozie.store;
016    
017    import java.sql.Blob;
018    import java.sql.Timestamp;
019    import java.util.ArrayList;
020    import java.util.HashMap;
021    import java.util.List;
022    import java.util.Map;
023    
024    import org.apache.oozie.util.db.Schema;
025    import org.apache.oozie.util.db.Schema.Column;
026    import org.apache.oozie.util.db.Schema.DBType;
027    import org.apache.oozie.util.db.Schema.Index;
028    import org.apache.oozie.util.db.Schema.Table;
029    
030    public class OozieSchema {
031    
032        private static String oozieDbName;
033    
034        private static final String OOZIE_VERSION = "0.1";
035    
036        public static final Map<Table, List<Column>> TABLE_COLUMNS = new HashMap<Table, List<Column>>();
037    
038        static {
039            for (Column column : OozieColumn.values()) {
040                List<Column> tColumns = TABLE_COLUMNS.get(column.table());
041                if (tColumns == null) {
042                    tColumns = new ArrayList<Column>();
043                    TABLE_COLUMNS.put(column.table(), tColumns);
044                }
045                tColumns.add(column);
046            }
047        }
048    
049        public static void setOozieDbName(String dbName) {
050            oozieDbName = dbName;
051        }
052    
053        public static enum OozieTable implements Table {
054            WORKFLOWS,
055            ACTIONS,
056            WF_PROCESS_INSTANCE,
057            VERSION;
058    
059            @Override
060            public String toString() {
061                return oozieDbName + "." + name().toUpperCase();
062            }
063        }
064    
065        public static enum OozieIndex implements Index {
066            IDX_WF_APPNAME(OozieColumn.WF_appName),
067            IDX_WF_USER(OozieColumn.WF_userName),
068            IDX_WF_GROUP(OozieColumn.WF_groupName),
069            IDX_WF_STATUS(OozieColumn.WF_status),
070            IDX_WF_EXTERNAL_ID(OozieColumn.WF_externalId),
071    
072            IDX_ACTIONS_BEGINTIME(OozieColumn.ACTIONS_pendingAge),
073            IDX_ACTIONS_WFID(OozieColumn.ACTIONS_wfId);
074    
075            final Column column;
076    
077            OozieIndex(Column column) {
078                this.column = column;
079            }
080    
081            public Column column() {
082                return column;
083            }
084        }
085    
086        public static enum OozieColumn implements Column {
087            // Process Instance Table
088            PI_wfId(OozieTable.WF_PROCESS_INSTANCE, String.class, true, 100),
089            PI_state(OozieTable.WF_PROCESS_INSTANCE, Blob.class, false),
090    
091            // WorkflowJob Table
092            WF_id(OozieTable.WORKFLOWS, String.class, true, 100),
093            WF_externalId(OozieTable.WORKFLOWS, String.class, false, 100),
094            WF_appName(OozieTable.WORKFLOWS, String.class, false, 100),
095            WF_appPath(OozieTable.WORKFLOWS, String.class, false, 255),
096            WF_conf(OozieTable.WORKFLOWS, String.class, false),
097            WF_protoActionConf(OozieTable.WORKFLOWS, String.class, false),
098            WF_logToken(OozieTable.WORKFLOWS, String.class, false, 100),
099            WF_status(OozieTable.WORKFLOWS, String.class, false, 100),
100            WF_run(OozieTable.WORKFLOWS, Long.class, false),
101            WF_lastModTime(OozieTable.WORKFLOWS, Timestamp.class, false),
102            WF_createdTime(OozieTable.WORKFLOWS, Timestamp.class, false),
103            WF_startTime(OozieTable.WORKFLOWS, Timestamp.class, false),
104            WF_endTime(OozieTable.WORKFLOWS, Timestamp.class, false),
105            WF_userName(OozieTable.WORKFLOWS, String.class, false, 100),
106            WF_groupName(OozieTable.WORKFLOWS, String.class, false, 100),
107            WF_authToken(OozieTable.WORKFLOWS, String.class, false),
108    
109            // Actions Table
110            ACTIONS_id(OozieTable.ACTIONS, String.class, true, 100),
111            ACTIONS_name(OozieTable.ACTIONS, String.class, false, 100),
112            ACTIONS_type(OozieTable.ACTIONS, String.class, false, 100),
113            ACTIONS_wfId(OozieTable.ACTIONS, String.class, false, 100),
114            ACTIONS_conf(OozieTable.ACTIONS, String.class, false),
115            ACTIONS_status(OozieTable.ACTIONS, String.class, false, 100),
116            ACTIONS_externalStatus(OozieTable.ACTIONS, String.class, false, 100),
117            ACTIONS_errorCode(OozieTable.ACTIONS, String.class, false, 100),
118            ACTIONS_errorMessage(OozieTable.ACTIONS, String.class, false),
119            ACTIONS_transition(OozieTable.ACTIONS, String.class, false, 100),
120            ACTIONS_retries(OozieTable.ACTIONS, Long.class, false),
121            ACTIONS_startTime(OozieTable.ACTIONS, Timestamp.class, false),
122            ACTIONS_endTime(OozieTable.ACTIONS, Timestamp.class, false),
123            ACTIONS_lastCheckTime(OozieTable.ACTIONS, Timestamp.class, false),
124            ACTIONS_data(OozieTable.ACTIONS, String.class, false),
125            ACTIONS_externalId(OozieTable.ACTIONS, String.class, false, 100),
126            ACTIONS_trackerUri(OozieTable.ACTIONS, String.class, false, 100),
127            ACTIONS_consoleUrl(OozieTable.ACTIONS, String.class, false, 100),
128            ACTIONS_executionPath(OozieTable.ACTIONS, String.class, false, 255),
129            ACTIONS_pending(OozieTable.ACTIONS, Boolean.class, false),
130            ACTIONS_pendingAge(OozieTable.ACTIONS, Timestamp.class, false),
131            ACTIONS_signalValue(OozieTable.ACTIONS, String.class, false, 100),
132            ACTIONS_logToken(OozieTable.ACTIONS, String.class, false, 100),
133    
134            // Version Table
135            VER_versionNumber(OozieTable.VERSION, String.class, false, 255);
136    
137            final Table table;
138            final Class<?> type;
139            int length = -1;
140            final boolean isPrimaryKey;
141    
142            OozieColumn(Table table, Class<?> type, boolean isPrimaryKey) {
143                this(table, type, isPrimaryKey, -1);
144            }
145    
146            OozieColumn(Table table, Class<?> type, boolean isPrimaryKey, int length) {
147                this.table = table;
148                this.type = type;
149                this.isPrimaryKey = isPrimaryKey;
150                this.length = length;
151            }
152    
153            private String getName() {
154                String tName = table.name();
155                return tName + "." + columnName();
156            }
157    
158            public String columnName() {
159                return name().split("_")[1].toLowerCase();
160            }
161    
162            @Override
163            public String toString() {
164                return getName();
165            }
166    
167            public Table table() {
168                return table;
169            }
170    
171            public Class<?> getType() {
172                return type;
173            }
174    
175            public int getLength() {
176                return length;
177            }
178    
179            public String asLabel() {
180                return name().toUpperCase();
181            }
182    
183            public boolean isPrimaryKey() {
184                return isPrimaryKey;
185            }
186        }
187    
188        /**
189         * Generates the create table SQL Statement
190         *
191         * @param table
192         * @param dbType
193         * @return SQL Statement to create the table
194         */
195        public static String generateCreateTableScript(Table table, DBType dbType) {
196            return Schema.generateCreateTableScript(table, dbType, TABLE_COLUMNS.get(table));
197        }
198    
199        /**
200         * Gets the query that will be used to validate the connection
201         *
202         * @param dbName
203         * @return
204         */
205        public static String getValidationQuery(String dbName) {
206            return "select count(" + OozieColumn.VER_versionNumber.columnName() + ") from " + dbName + "."
207                    + OozieTable.VERSION.name().toUpperCase();
208        }
209    
210        /**
211         * Generates the Insert statement to insert the OOZIE_VERSION to table
212         *
213         * @param dbName
214         * @return
215         */
216        public static String generateInsertVersionScript(String dbName) {
217            return "INSERT INTO " + dbName + "." + OozieTable.VERSION.name().toUpperCase() + "("
218                    + OozieColumn.VER_versionNumber.columnName() + ") VALUES(" + OOZIE_VERSION + ")";
219        }
220    
221        /**
222         * Gets the Oozie Schema Version
223         *
224         * @return
225         */
226        public static String getOozieVersion() {
227            return OOZIE_VERSION;
228        }
229    }