Day: June 9, 2009

  • Remove/Change default constraints sql 2000/2005

    Problem

    When we add default constraint on a field it is automatically assigned a name in following format

    Format:
    DF__tablename__PARTOFFIELDNAME__HASHCODE
    Example:
    DF__scheduled__CREAT__00DF2177
    DF__scheduled__MODIF__01D345B0
    

    HashCode part of the format is different on each database so we can’t just find the name of constraint and use that in our alter script. That’s when sysobjects table comes to the rescue.

    This will list all the default field values for all tables

    SELECT OBJECT_NAME(ID) AS NameofConstraint,
    OBJECT_NAME(parent_obj) AS TableName
    FROM sysobjects
     WHERE xtype = 'D' 
    

    from here we can construct our TSQL script to suit our needs.

    Solution

    1. Get default fields of interes t(ConstraintName, TableName)
    2. Drop each constraint
    3. Add new default constraint with a NAME
    /**
    @Desc: Remove default constraints from a given table, then add new default constraint
    2000/2005 compatible
    @Author Greg B.
    **/
    USE [mydb]
    GO
    
    BEGIN TRANSACTION
    GO
    
    Declare MyCursor Cursor For
    
    SELECT OBJECT_NAME(ID) AS NameofConstraint,
    OBJECT_NAME(parent_obj) AS TableName
    FROM sysobjects
     WHERE xtype = 'D' 
    AND (OBJECT_NAME(parent_obj) = 'procedures' AND  OBJECT_NAME(ID) LIKE '%DF__procedure__INHER%')
    
    OR 
    (
     OBJECT_NAME(parent_obj) = 'subarea'
    AND   (OBJECT_NAME(ID) LIKE '%DF__subarea__ABS_INH__%') 
     OR (OBJECT_NAME(ID) LIKE '%DF__subarea__ASSIGNE__%') 
    ) 
    
    
    DECLARE @SQLScript NVARCHAR(300)
    
    Declare @NameofConstraint VARCHAR(255) 
    Declare @SchemaName VARCHAR(255) 
    Declare @TableName VARCHAR(255) 
    Declare @ConstraintType VARCHAR(255) 
    
    Open MyCursor
    Declare @Count int
    Select @Count = 0 
    FETCH NEXT FROM MyCursor INTO @NameofConstraint, @TableName
    WHILE @@FETCH_STATUS = 0
    BEGIN
    	--PINT 'RECORD='+@NameofConstraint +' :: '+@TableName
    	Select @SQLScript= 'ALTER TABLE '+ @TableName +' DROP CONSTRAINT '+@NameofConstraint
    	EXEC sp_executesql @SQLScript
    	Select @Count=@Count+1
    	--Advance to next record
    	FETCH NEXT FROM MyCursor INTO @NameofConstraint,@TableName
    END
    
    Close MyCursor
    DEALLOCATE MyCursor
    
    if @Count != 0
    BEGIN
    print 'Adding alter'
    -- Now we add the constrains back again to the tables with standarized names
      ALTER TABLE [dbo].[procedures] ADD CONSTRAINT DF_PROCEDURE_INHERENT_RISK DEFAULT ((1)) FOR [INHERENT_RISK]
      ALTER TABLE [dbo].[subarea] ADD CONSTRAINT DF_SUBAREA_ABS_INHERENT_RISK DEFAULT ((1)) FOR [ABS_INHERENT_RISK]
      ALTER TABLE [dbo].[subarea] ADD CONSTRAINT DF_SUBAREA_ASSIGNED_INHERENT_RISK DEFAULT ((1)) FOR [ASSIGNED_INHERENT_RISK]
    END
    
    COMMIT TRANSACTION 
    
    IF @@TRANCOUNT > 0
    BEGIN
        ROLLBACK TRAN
    END 
    GO
    
  • Serving resources using Resource PhaseListener

    PhaseListener designed to serve resources like css, javascript, images, pdf etc.. from jar file

    ResourcePhaseListener.java

    All required files can be downloaded here.

    package com.gregbugaj.jsfdump.console;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.activation.MimetypesFileTypeMap;
    import javax.faces.context.FacesContext;
    import javax.faces.event.PhaseEvent;
    import javax.faces.event.PhaseId;
    import javax.faces.event.PhaseListener;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletResponse;
    
    import org.w3c.dom.Document;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    
    import com.gregbugaj.jsfdump.util.JarUtil;
    import com.gregbugaj.jsfdump.util.XMLUtil;
    /**
     * Serve resources from jar file  back to the user by specifying resource name in resource-config.xml
     * 
     * This works with following syntax if faces servlet is *.jsf  /jsfdump/resource/script.js.jsf
     * or  /jsfdump/resource/script.js if faces servlet is *.*
     * 
     * @author devil
     *
     */
    @SuppressWarnings("serial")
    public class ResourcePhaseListener implements PhaseListener {
    	//This is how the resource will be accessed ex /jsfdump/resource/script.js
    	private static final String RESOURCE_PREFIX = "/jsfdump/resource/";
    	//Location of where the js, img, css etc files reside inside the jar, we could also placed them in META-INF folder
    	private static final String RESOURCE_PATH = "/com/gregbugaj/jsfdump/resources/";
    	
    	private static Map resources=new HashMap();
    	private boolean isLoaded;
    
    	@Override
    	public void afterPhase(PhaseEvent event) {
    		FacesContext facesContext=event.getFacesContext();
    		String rootId=facesContext.getViewRoot().getViewId();
    		//Clean up key
    		String key=rootId.replace(RESOURCE_PREFIX, "");
    		key=key.replace(".xhtml", "");
    		key=key.replace(".jsf", "");
    		if(!rootId.startsWith(RESOURCE_PREFIX)){
    			return; 
    		}
    		
    		//Lazy loading
    		if(!isLoaded){
    			isLoaded=initResources();
    		}	
    		String resourceName=resources.get(key);
    		//Location of resources inside the jar file
    		String fileName=RESOURCE_PATH+resourceName;
    		InputStream resourceStream=JarUtil.getStreamFromJar(fileName);
    		HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
    		response.setCharacterEncoding("UTF-8");
    		ServletOutputStream sos = null;
    		try {
    			sos = response.getOutputStream();
    			if(resourceStream!=null){
    				response.setStatus(HttpServletResponse.SC_OK);
    				//Resolve mime type, required that we have activation.jar loaded
    				//Additional mime types can be defined in /META-INF/mimes.types  {@link http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/activation/MimetypesFileTypeMap.html }
    				String contentType = new MimetypesFileTypeMap().getContentType(fileName);
    				response.setContentType(contentType);
    				byte[] buffer= new byte[1024];
    				for (int bytesRead = 0; (bytesRead = resourceStream.read(buffer, 0, buffer.length)) > 0;)
    				{
    					sos.write(buffer, 0, bytesRead);
    				}
    			}else{
    				//Resource not found
    				response.setStatus(HttpServletResponse.SC_NOT_FOUND);
    				response.setContentType("text/html");
    			}
    			sos.flush();
    			sos.close();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		facesContext.responseComplete();
    	}
    
    	@Override
    	public void beforePhase(PhaseEvent event) {
    		//Do nothing
    	}
    
    	/**
    	 * Load resource mapping from resource-config.xml
    	 * @return true if we successfully loded resource
    	 */
    	private boolean initResources() {
    		boolean retVal=true;
    		InputStream stream=null;	
    		try {
    			stream=JarUtil.getStreamFromJar("/META-INF/resource-config.xml");
    			Document document=XMLUtil.getXmlDocument(stream);
    			NodeList resourceNodes=XMLUtil.extract("/resources/resource", document);
    			for(int i=0;i
    

    resource-config.xml

    This is where we define resources that we will be serving. One reasons we use xml configuration is to prevent security breaches.

      
      
    	
    	
    	
      
    

    Two common ways to access the resources are
    If faces servlet is *.jsf /jsfdump/resource/script.js.jsf
    Of /jsfdump/resource/script.js if faces servlet is *.*

    META-INF/mime.types

    This is where we add additional mime types, requires that we have activation.jar loaded More info

    This file is not required but it helps, for example png files resolve to application/octet-stream rather than image/x-png

    Examples