/* * Copyright 2004-2005 OpenSymphony * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * */ /* * Previously Copyright (c) 2001-2004 James House */ package org.quartz.impl.jdbcjobstore; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.math.BigDecimal; import java.sql.Blob; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.commons.logging.Log; import org.quartz.CronTrigger; import org.quartz.JobDetail; import org.quartz.SimpleTrigger; import org.quartz.Trigger; /** *

* This is a driver delegate for the MSSQL JDBC driver. *

* * @author Jeffrey Wescott */ public class MyMSSQLDelegate extends StdJDBCDelegate { /** *

* Create new MSSQLDelegate instance. *

* * @param log * the logger to use during execution * @param tablePrefix * the prefix of all table names */ public MyMSSQLDelegate(Log log, String tablePrefix, String instanceId) { super(log, tablePrefix, instanceId); } public MyMSSQLDelegate(Log log, String tablePrefix, String instanceId, Boolean useProperties) { super(log, tablePrefix, instanceId, useProperties); } //--------------------------------------------------------------------------- // protected methods that can be overridden by subclasses //--------------------------------------------------------------------------- /** *

* This method should be overridden by any delegate subclasses that need * special handling for BLOBs. The default implementation uses standard * JDBC java.sql.Blob operations. *

* * @param rs * the result set, already queued to the correct row * @param colName * the column name for the BLOB * @return the deserialized Object from the ResultSet BLOB * @throws ClassNotFoundException * if a class found during deserialization cannot be found * @throws IOException * if deserialization causes an error */ protected Object getObjectFromBlob(ResultSet rs, String colName) throws ClassNotFoundException, IOException, SQLException { byte[] bais_bytes = rs.getBytes(colName); if (bais_bytes.length == 0) return null; Object obj = null; ObjectInputStream in = null; try { in = new ObjectInputStream(new ByteArrayInputStream(bais_bytes)); obj = in.readObject(); } catch (EOFException e) { throw new IOException("Unable to load object from blob: " + e.getMessage()); } finally { if(in != null) in.close(); } return obj; } protected Object getJobDetailFromBlob(ResultSet rs, String colName) throws ClassNotFoundException, IOException, SQLException { if (canUseProperties()) { Blob blobLocator = rs.getBlob(colName); if ((blobLocator != null) && (rs.wasNull() == false)){ InputStream binaryInput = blobLocator.getBinaryStream(); return binaryInput; } else { return null; } } return getObjectFromBlob(rs, colName); } public int insertTrigger(Connection conn, Trigger trigger, String state, JobDetail jobDetail) throws SQLException, IOException { ByteArrayOutputStream baos = null; if(trigger.getJobDataMap().size() > 0) { baos = serializeJobData(trigger.getJobDataMap()); } PreparedStatement ps = null; int insertResult = 0; try { ps = conn.prepareStatement(rtp(INSERT_TRIGGER)); ps.setString(1, trigger.getName()); ps.setString(2, trigger.getGroup()); ps.setString(3, trigger.getJobName()); ps.setString(4, trigger.getJobGroup()); setBoolean(ps, 5, trigger.isVolatile()); ps.setString(6, trigger.getDescription()); ps.setBigDecimal(7, new BigDecimal(String.valueOf(trigger .getNextFireTime().getTime()))); long prevFireTime = -1; if (trigger.getPreviousFireTime() != null) { prevFireTime = trigger.getPreviousFireTime().getTime(); } ps.setBigDecimal(8, new BigDecimal(String.valueOf(prevFireTime))); ps.setString(9, state); if (trigger.getClass() == SimpleTrigger.class) { ps.setString(10, TTYPE_SIMPLE); } else if (trigger.getClass() == CronTrigger.class) { ps.setString(10, TTYPE_CRON); } else { ps.setString(10, TTYPE_BLOB); } ps.setBigDecimal(11, new BigDecimal(String.valueOf(trigger .getStartTime().getTime()))); long endTime = 0; if (trigger.getEndTime() != null) { endTime = trigger.getEndTime().getTime(); } ps.setBigDecimal(12, new BigDecimal(String.valueOf(endTime))); ps.setString(13, trigger.getCalendarName()); ps.setInt(14, trigger.getMisfireInstruction()); if (baos != null) ps.setBytes(15, baos.toByteArray()); else { ps.setBytes(15, new byte[0]); } ps.setInt(16, trigger.getPriority()); insertResult = ps.executeUpdate(); } finally { closeStatement(ps); } if (insertResult > 0) { String[] trigListeners = trigger.getTriggerListenerNames(); for (int i = 0; trigListeners != null && i < trigListeners.length; i++) { insertTriggerListener(conn, trigger, trigListeners[i]); } } return insertResult; } } // EOF