001: /*
002: * SalomeTMF is a Test Management Framework
003: * Copyright (C) 2005 France Telecom R&D
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 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, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: *
019: * @author Marche Mikael
020: *
021: * Contact: mikael.marche@rd.francetelecom.com
022: */
023:
024: package org.objectweb.salome_tmf.databaseSQL;
025:
026: import java.net.InetAddress;
027: import java.sql.PreparedStatement;
028: import java.sql.ResultSet;
029: import java.util.Properties;
030:
031: import org.objectweb.salome_tmf.api.Api;
032: import org.objectweb.salome_tmf.api.ApiConstants;
033: import org.objectweb.salome_tmf.api.Util;
034: import org.objectweb.salome_tmf.api.data.LockInfoWrapper;
035: import org.objectweb.salome_tmf.api.sql.ISQLEngine;
036: import org.objectweb.salome_tmf.api.sql.ISQLSalomeLock;
037: import org.objectweb.salome_tmf.api.sql.LockException;
038:
039: public class SQLEngine implements ISQLEngine {
040:
041: static Properties addSqlQuery;
042: static Properties deleteSqlQuery;
043: static Properties updateSqlQuery;
044: static Properties selectSqlQuery;
045: static Properties comonQuery;
046:
047: static DataBase db;
048:
049: static int mysqlLock = 1; //-1 = none , 0 = mysql, 1 = salome,
050: static boolean isLock = false;
051: static boolean specialLock = false;
052: static boolean specLock = false;
053: static boolean lockOnQuery = true;
054: static int _code = -1;
055:
056: //static int lockCode = 0;
057: static int nbLockTry = 3;
058: static int waitLockTime = 1000;
059: static ISQLSalomeLock pSQLSalomeLock = null;
060: static int projectID = 0;
061: static int personneID = 0;
062: static int pid = 0;
063:
064: static int idTrans = -1;
065: public static int tmpIdTrans = -1;
066: static java.util.Random idCalcul = new java.util.Random(1000000);
067:
068: static String addToLockWrite = "";
069: static String addToLockRead = "";
070: static boolean exitOnErrorComit = true;
071:
072: //static File logFile;
073: //static FileOutputStream logFileOutput;
074:
075: static void initSQLEngine(DataBase database, boolean doLockOnQuery,
076: String _SQLBase, int locktype) throws Exception {
077: String SQLBase = DatabaseConstants.SQLBASE;
078: if (_SQLBase != null) {
079: SQLBase = _SQLBase;
080: }
081: mysqlLock = locktype;
082: if (idTrans != -1) {
083: idTrans = -1;
084: isLock = false;
085: specialLock = false;
086: specLock = false;
087: lockOnQuery = true;
088: _code = -1;
089: //throw new Exception ("Previous Session not correct");
090: }
091: Util
092: .log("[SQLEngine->initSQLEngine] get addSqlQuery properties "
093: + DatabaseConstants.ADD_SQL_QUERY_FILE_PATH);
094: addSqlQuery = Util.getPropertiesStream(SQLEngine.class
095: .getResourceAsStream(SQLBase
096: + DatabaseConstants.ADD_SQL_QUERY_FILE_PATH));
097: Util
098: .log("[SQLEngine->initSQLEngine] get comonQuery properties "
099: + DatabaseConstants.COMMON_SQL_QUERY_FILE_PATH);
100: comonQuery = Util
101: .getPropertiesStream(SQLEngine.class
102: .getResourceAsStream(SQLBase
103: + DatabaseConstants.COMMON_SQL_QUERY_FILE_PATH));
104: Util
105: .log("[SQLEngine->initSQLEngine] get updateSqlQuery properties "
106: + DatabaseConstants.UPDATE_SQL_QUERY_FILE_PATH);
107: updateSqlQuery = Util
108: .getPropertiesStream(SQLEngine.class
109: .getResourceAsStream(SQLBase
110: + DatabaseConstants.UPDATE_SQL_QUERY_FILE_PATH));
111: Util
112: .log("[SQLEngine->initSQLEngine] get selectSqlQuery properties "
113: + DatabaseConstants.SELECT_SQL_QUERY_FILE_PATH);
114: selectSqlQuery = Util
115: .getPropertiesStream(SQLEngine.class
116: .getResourceAsStream(SQLBase
117: + DatabaseConstants.SELECT_SQL_QUERY_FILE_PATH));
118: Util
119: .log("[SQLEngine->initSQLEngine] get deleteSqlQuery properties "
120: + DatabaseConstants.DELETE_SQL_QUERY_FILE_PATH);
121: deleteSqlQuery = Util
122: .getPropertiesStream(SQLEngine.class
123: .getResourceAsStream(SQLBase
124: + DatabaseConstants.DELETE_SQL_QUERY_FILE_PATH));
125:
126: if (database == null) {
127: throw new Exception(
128: "[SQLEngine:initSQLEngine] Database is null");
129: }
130: lockOnQuery = doLockOnQuery;
131: db = database;
132:
133: pid = (int) ((database.hashCode()) * (System
134: .currentTimeMillis()));
135: /*if (Api.isDEBUG()){
136: try {
137: String tmpDir = System.getProperties().getProperty("java.io.tmpdir");
138: String fs = System.getProperties().getProperty("file.separator");
139: logFile = new File(tmpDir + fs + "database.log");
140: logFile.createNewFile();
141: logFileOutput = new FileOutputStream (logFile);
142:
143: } catch (Exception e){
144:
145: }
146: }*/
147: }
148:
149: static void initDB(DataBase database) throws Exception {
150: if (database == null) {
151: throw new Exception(
152: "[SQLEngine:initSQLEngine] Database is null");
153: }
154: if (idTrans != -1) {
155: idTrans = -1;
156: isLock = false;
157: specialLock = false;
158: specLock = false;
159: lockOnQuery = true;
160: _code = -1;
161: //throw new Exception ("Previous Session not correct");
162: }
163: db = database;
164: pid = (int) ((database.hashCode()) * (System
165: .currentTimeMillis()));
166: }
167:
168: static PreparedStatement getSQLAddQuery(String queryName)
169: throws Exception {
170: Util.log("[SQLEngine->getSQLAddQuery]" + queryName);
171: String sql = addSqlQuery.getProperty(queryName);
172: Util.log("[SQLEngine->getSQLAddQuery] sql is " + sql);
173: PreparedStatement prep = db.prepareStatement(sql);
174: return prep;
175: }
176:
177: static PreparedStatement getSQLCommonQuery(String queryName)
178: throws Exception {
179: Util.log("[SQLEngine->getSQLCommonQuery]" + queryName);
180: String sql = comonQuery.getProperty(queryName);
181: Util.log("[SQLEngine->getSQLCommonQuery] sql is " + sql);
182: PreparedStatement prep = db.prepareStatement(sql);
183: return prep;
184: }
185:
186: static PreparedStatement getSQLSelectQuery(String queryName)
187: throws Exception {
188: Util.log("[SQLEngine->getSQLSelectQuery]" + queryName);
189: String sql = selectSqlQuery.getProperty(queryName);
190: Util.log("[SQLEngine->getSQLSelectQuery] sql is " + sql);
191: PreparedStatement prep = db.prepareStatement(sql);
192: return prep;
193: }
194:
195: static PreparedStatement getSQLUpdateQuery(String queryName)
196: throws Exception {
197: Util.log("[SQLEngine->getSQLUpdateQuery]" + queryName);
198: String sql = updateSqlQuery.getProperty(queryName);
199: Util.log("[SQLEngine->getSQLUpdateQuery] sql is " + sql);
200: PreparedStatement prep = db.prepareStatement(sql);
201: return prep;
202: }
203:
204: static PreparedStatement getSQLDeleteQuery(String queryName)
205: throws Exception {
206: Util.log("[SQLEngine->getSQLDeleteQuery]" + queryName);
207: String sql = deleteSqlQuery.getProperty(queryName);
208: Util.log("[SQLEngine->getSQLDeleteQuery] sql is " + sql);
209: PreparedStatement prep = db.prepareStatement(sql);
210: return prep;
211: }
212:
213: static PreparedStatement getStatement(String sql) throws Exception {
214: PreparedStatement prep = db.prepareStatement(sql);
215: return prep;
216: }
217:
218: static synchronized int runAddQuery(PreparedStatement prep)
219: throws Exception {
220: return prep.executeUpdate();
221: }
222:
223: static synchronized int runDeleteQuery(PreparedStatement prep)
224: throws Exception {
225: return prep.executeUpdate();
226: }
227:
228: static synchronized int runUpdateQuery(PreparedStatement prep)
229: throws Exception {
230: return prep.executeUpdate();
231: }
232:
233: static synchronized ResultSet runSelectQuery(PreparedStatement prep)
234: throws Exception {
235: return prep.executeQuery();
236: }
237:
238: public synchronized int beginTransDB(int lock_code, int type)
239: throws Exception {
240: return beginTransaction(lock_code, type);
241: }
242:
243: public synchronized void commitTransDB(int type) throws Exception {
244: commitTrans(type);
245: }
246:
247: public synchronized void rollBackTransDB(int type) throws Exception {
248: rollBackTrans(type);
249: }
250:
251: public synchronized void rollForceBackTransDB(int type) {
252: //writeFileLog("Force RollBack Trans : " + type);
253: try {
254: rollBackTrans(type);
255: } catch (Exception e) {
256: try {
257: rollBackTrans(type);
258: } catch (Exception e1) {
259: try {
260: rollBackTrans(type);
261: } catch (Exception e2) {
262:
263: }
264: }
265: }
266: }
267:
268: /*public synchronized void doComit() throws Exception {
269: int transNumber = beginTransaction(ApiConstants.LOADING);
270: commitTrans(transNumber);
271: }
272:
273: static public synchronized void doComitData() throws Exception {
274: int transNumber = beginTransaction(ApiConstants.LOADING);
275: commitTrans(transNumber);
276: }*/
277:
278: static public synchronized int beginTransaction(int lock_code,
279: int type) throws Exception {
280: if (idTrans == -1) {
281: _code = type;
282:
283: //if mysqlock = 1
284: if (lockOnQuery) {
285: if (isLock == false && specLock == false) {
286: if (_code != ApiConstants.COMMON_REQ
287: && canLock(_code)) {
288: lockReadWrite(lock_code, type);
289: }
290: }
291: }
292:
293: idTrans = idCalcul.nextInt();
294: Util.log("[SQLEngine] Start the Transition : " + idTrans
295: + ", with code " + _code);
296: //if (_code != ApiConstants.LOADING) {
297: db.beginTrans(); //if mysqlock = -1 or 1
298: //}
299:
300: // if mysqlock = 0 -> lock table
301: return idTrans;
302: }
303: return -1;
304: }
305:
306: static synchronized public void commitTrans(int id)
307: throws Exception {
308: if (idTrans != -1) {
309: if (id == idTrans) {
310: Util.log("[SQLEngine] Commit the Transition : " + id);
311: idTrans = -1;
312:
313: try {
314: //if (_code != ApiConstants.LOADING) {
315: db.commit();
316: //}
317: } catch (Exception e) {
318: if (exitOnErrorComit) {
319: e.printStackTrace();
320: System.exit(1);
321: }
322: }
323: try {
324: if (lockOnQuery) {
325: if (isLock && specLock == false) {
326: if (_code != ApiConstants.COMMON_REQ
327: && canLock(_code)) {
328: unLock();
329: }
330: }
331: }
332:
333: } catch (Exception e) {
334: if (exitOnErrorComit) {
335: e.printStackTrace();
336: System.exit(1);
337: }
338: }
339: //writeFileLog("Commit Trans : " + id);
340:
341: if (_code != -1 && _code != ApiConstants.COMMON_REQ) {
342: Util.log("[SQLEngine] dispatchChange : " + _code);
343: //Api.dispatchChange(_code);
344: if (Api.isNET_CHANGE_TRACK()) {
345: //if (SQLObjectFactory.pChangeListener != null) {
346: SQLObjectFactory.pChangeListener
347: .addChange(_code);
348: }
349: }
350: }
351: }
352: }
353:
354: static synchronized public void rollBackTrans(int id)
355: throws Exception {
356: if (idTrans != -1) {
357: if (id == idTrans) {
358: Util.log("[SQLEngine] RollBack the Transition : " + id);
359: idTrans = -1;
360: try {
361: //if (_code != ApiConstants.LOADING) {
362: db.rollback();
363: //}
364: } catch (Exception e) {
365: if (exitOnErrorComit) {
366: e.printStackTrace();
367: System.exit(1);
368: }
369: }
370: try {
371: if (isLock && specLock == false) {
372: if (_code != ApiConstants.COMMON_REQ
373: && canLock(_code)) {
374: unLock();
375: }
376: }
377: } catch (Exception e) {
378: if (exitOnErrorComit) {
379: e.printStackTrace();
380: System.exit(1);
381: }
382: }
383: //writeFileLog("RollBack Trans : " + id);
384:
385: }
386: }
387: }
388:
389: static void lockReadWrite(int lock_code, int action_code)
390: throws Exception {
391: if (isLock == true) {
392: throw new Exception(
393: "[SQLEngine->lockReadWrite] Database is already locked");
394: }
395: if (lock_code == 0) {
396: return;
397: }
398: if (!specialLock) {
399: if (mysqlLock == 0) {
400: Util.log("[SQLEngine] Do Lock for transition code : "
401: + _code);
402: lockRead();
403: lockWrite();
404: } else if (mysqlLock == 1) {
405: isLock = lockApplicative(lock_code, action_code);
406: } else {
407: isLock = false;
408: }
409: }
410: }
411:
412: static void lockRead() throws Exception { //Called only from lockReadWrite
413: Util.log("[SQLEngine] Do lock Read");
414: if (mysqlLock == 0) {
415: PreparedStatement prep;
416: String sql = comonQuery.getProperty("lockALLREAD");
417: sql += addToLockRead;
418: Util.log("[SQLEngine->getSQLCommonQuery] sql is " + sql);
419: prep = db.prepareStatement(sql);
420: prep.executeUpdate();
421: isLock = true;
422: } else {
423:
424: }
425: }
426:
427: static void lockWrite() throws Exception {//Called only from lockReadWrite
428: Util.log("[SQLEngine] Do lock Write");
429: if (mysqlLock == 0) {
430: PreparedStatement prep;
431:
432: String sql = comonQuery.getProperty("lockALLWRITE");
433: sql += addToLockWrite;
434: Util.log("[SQLEngine->getSQLCommonQuery] sql is " + sql);
435: prep = db.prepareStatement(sql);
436:
437: prep.executeUpdate();
438: isLock = true;
439: } else {
440:
441: }
442: }
443:
444: static void lockTestPlan() throws Exception { //Called only from lockTPlan
445: Util.log("[SQLEngine] Do lock All");
446: if (mysqlLock == 0) {
447: PreparedStatement prep;
448: prep = getSQLCommonQuery("lock");
449: prep.executeUpdate();
450: isLock = true;
451: specialLock = true;
452: } else {
453: /* TODO */
454: }
455: }
456:
457: static void unLock() throws Exception {
458: if (mysqlLock == 0) {
459: if (isLock == false) {
460: throw new Exception(
461: "[SQLEngine->unLock] Database is not locked");
462: }
463: if (!specialLock) {
464: Util.log("[SQLEngine] Do UnLock for transition code : "
465: + _code);
466: PreparedStatement prep;
467: prep = getSQLCommonQuery("unlock");
468: prep.executeUpdate();
469: isLock = false;
470: }
471: } else if (mysqlLock == 1) {
472: if (isLock) {
473: unLockApplicativeLock();
474: }
475: isLock = false;
476: } else {
477: isLock = false;
478: }
479: }
480:
481: /************ Applicative lock *******************/
482:
483: static boolean canLock(int code) {
484: if (code != ApiConstants.READ_LOCK
485: && code != ApiConstants.DELETE_LOCK
486: && code != ApiConstants.INSERT_LOCK) {
487: return true;
488: }
489: return false;
490: }
491:
492: public void setConnexionInfo(int _projectID, int _personneID) {
493: projectID = _projectID;
494: personneID = _personneID;
495: pSQLSalomeLock = Api.getISQLObjectFactory().getISQLSalomeLock();
496: }
497:
498: public int getProjectID() {
499: return projectID;
500: }
501:
502: public int getPersonneID() {
503: return personneID;
504: }
505:
506: static void unLockApplicativeLock() throws Exception {
507: if (pSQLSalomeLock != null && projectID > 0) {
508: try {
509: Util.log("[SQLEngine] Do UnLock for transition code : "
510: + _code);
511: pSQLSalomeLock.delete(projectID, pid);
512: } catch (Exception e) {
513: try {
514: Util
515: .log("[SQLEngine] Do UnLock for transition code : "
516: + _code);
517: pSQLSalomeLock.delete(projectID, pid);
518: } catch (Exception e1) {
519: try {
520: Util
521: .log("[SQLEngine] Do UnLock for transition code : "
522: + _code);
523: pSQLSalomeLock.delete(projectID, pid);
524: } catch (Exception e2) {
525: throw new LockException(
526: "Cannot unlock the DataBase, restart salome",
527: LockException.DELETE_LOCK);
528: // DO SYSTEM EXIT
529: }
530: }
531: }
532: }
533: }
534:
535: static boolean lockApplicative(int lock_code, int action_code)
536: throws Exception {
537: if (lock_code == 0) {
538: return false;
539: }
540:
541: boolean doLock = false;
542: Util.log("[SQLEngine] Do UnLock " + lock_code
543: + " for transition code : " + _code);
544: if (pSQLSalomeLock != null && projectID > 0) {
545: LockInfoWrapper pLockInfo = pSQLSalomeLock
546: .isLock(projectID);
547: if (pLockInfo != null) {
548: if (pid == pLockInfo.getPid()) {
549: throw new LockException(
550: "Cannot lock the DataBase, please restart salome",
551: LockException.DOLOCK);
552: }
553: if (canLock(lock_code, pLockInfo.getLock_code())) {
554: insertApplicativeLock(lock_code, action_code);
555: doLock = true;
556: } else {
557: int tryLock = 0;
558: while (!doLock && tryLock < nbLockTry) {
559: try {
560: Thread.sleep(waitLockTime);
561: pLockInfo = pSQLSalomeLock
562: .isLock(projectID);
563: if (pLockInfo != null) {
564: if (pid == pLockInfo.getPid()) {
565: throw new LockException(
566: "Cannot lock the DataBase, please restart salome",
567: LockException.DOLOCK);
568: }
569: if (canLock(lock_code, pLockInfo
570: .getLock_code())) {
571: insertApplicativeLock(lock_code,
572: action_code);
573: doLock = true;
574: } else {
575: tryLock++;
576: }
577: } else {
578: insertApplicativeLock(lock_code,
579: action_code);
580: doLock = true;
581: }
582: } catch (Exception e) {
583: tryLock++;
584: }
585: }
586: }
587: } else {
588: insertApplicativeLock(lock_code, action_code);
589: doLock = true;
590: }
591: if (doLock == false) {
592: throw new LockException(
593: "DataBase is locked, please try later or delete lock",
594: LockException.DOLOCK);
595: }
596: }
597: return doLock;
598: }
599:
600: static void insertApplicativeLock(int lock_code, int action_code)
601: throws Exception {
602: if (pSQLSalomeLock != null && projectID > 0) {
603: try {
604: Util.log("[SQLEngine] Do Lock for transition code : "
605: + _code);
606: pSQLSalomeLock.insert(projectID, personneID, lock_code,
607: action_code, "", pid);
608: } catch (Exception e) {
609: try {
610: Util
611: .log("[SQLEngine] Do Lock for transition code : "
612: + _code);
613: pSQLSalomeLock.insert(projectID, personneID,
614: lock_code, action_code, "", pid);
615: } catch (Exception e1) {
616: try {
617: Util
618: .log("[SQLEngine] Do Lock for transition code : "
619: + _code);
620: pSQLSalomeLock.insert(projectID, personneID,
621: lock_code, action_code, "", pid);
622: } catch (Exception e2) {
623: e2.printStackTrace();
624: throw new LockException(
625: "Cannot lock the DataBase, please try later or restart salome",
626: LockException.INSERT_LOCK);
627: }
628: }
629: }
630: }
631: }
632:
633: static boolean canLock(int lock_code_todo, int lock_code_exist) {
634: int mask = (lock_code_todo & lock_code_exist);
635: Util
636: .log("[SQLEngine] Lock " + lock_code_exist
637: + " existe, an try lock : " + lock_code_todo
638: + "(mask = "
639: + (lock_code_todo & lock_code_exist) + ")");
640: if (mask == 0) {
641: return true;
642: }
643: return false;
644: }
645:
646: /************ Special Allow use in case of cascade delete or update *******************/
647:
648: static boolean specialAllow = false;
649:
650: static void setSpecialAllow(boolean special_allow) {
651: specialAllow = special_allow;
652: }
653:
654: static boolean isSpecialAllow() {
655: return specialAllow;
656: }
657:
658: /******************** ISQLEngine Implentation ****************************************/
659:
660: public boolean isClose() {
661: try {
662: if (db != null) {
663: return db.cnt.isClosed();
664: } else {
665: return true;
666: }
667: } catch (Exception e) {
668: return true;
669: }
670: }
671:
672: public boolean isOpen() {
673: return !isClose();
674: }
675:
676: public void close() throws Exception {
677: /*try {
678: if (logFileOutput != null){
679: logFileOutput.flush();
680: logFileOutput.close();
681: }
682: } catch (Exception e){
683:
684: }*/
685: Util.log("[SQLEngine->close] close connection " + db.cnt);
686: db.cnt.close();
687: db = null;
688: }
689:
690: public void addSQLLoackRead(String table) {
691: if (!(addToLockRead.indexOf(table) > 0)) {
692: addToLockRead += "," + table;
693: }
694: }
695:
696: public void addSQLLoackWrite(String table) {
697: if (!(addToLockWrite.indexOf(table) > 0)) {
698: addToLockWrite += "," + table;
699: }
700: }
701:
702: public synchronized boolean isLock() {
703: return isLock;
704: }
705:
706: /* public void lockAll() throws Exception{
707: if (mysqlLock){
708: lockReadWrite();
709: } else {
710: //TODO
711: return;
712: }
713: }*/
714:
715: public void lockTPlan() throws Exception {
716: Util.log("[SQLEngine] Lock Test plan");
717: if (mysqlLock == 0) {
718: lockTestPlan();
719: } else if (mysqlLock == 1) {
720: /*TODO*/
721: return;
722: } else {
723:
724: }
725: }
726:
727: /*public void unLockAll() throws Exception{
728: if (mysqlLock == 0){
729: unLock();
730: } else if (mysqlLock ==1) {
731: //TODO
732: return;
733: } else {
734: return;
735: }
736: }*/
737:
738: public void unLockTPlan() throws Exception {
739: if (mysqlLock == 0) {
740: Util.log("[SQLEngine] unLock Test plan");
741: specialLock = false;
742: unLock();
743: } else if (mysqlLock == 1) {
744: /*TODO*/
745: return;
746: } else {
747: return;
748: }
749: }
750:
751: public static DataBase getDb() {
752: return db;
753: }
754:
755: public static void setDb(DataBase db) {
756: SQLEngine.db = db;
757: }
758:
759: public static int getIdTrans() {
760: return idTrans;
761: }
762:
763: public static void setIdTrans(int idTrans) {
764: SQLEngine.idTrans = idTrans;
765: }
766:
767: /////////////////////////////////////////////////////////////////////////
768:
769: /*static private void writeFileLog(String s){
770: try {
771: String toWrite = s + "\n";
772: logFileOutput.write(toWrite.getBytes());
773: } catch(Exception e){
774:
775: }
776: }*/
777: }
|