head	1.28;
access;
symbols
	TIGRIS_1_1_0RC2:1.3.6.1
	TIGRIS_1_1_0RC1:1.3.6.1
	TIGRIS_1_1:1.3.6.1.0.2
	TIGRIS_1_0_8:1.3.6.1
	TIGRIS_1_0_8RC3:1.3.6.1
	TIGRIS_1_0_8RC2:1.3.6.1
	TIGRIS_1_0_8RC1:1.3.6.1
	TIGRIS_1_0_7:1.3.6.1
	TIGRIS_1_0_7RC3:1.3.6.1
	TIGRIS_1_0_7RC2:1.3.6.1
	TIGRIS_1_0_7RC1:1.3.6.1
	TIGRIS_1_0_6:1.3.6.1
	TIGRIS_1_0_6RC5:1.3.6.1
	TIGRIS_1_0_6RC4:1.3.6.1
	TIGRIS_1_0_6RC3:1.3.6.1
	TIGRIS_1_0_6RC2:1.3.6.1
	TIGRIS_1_0_6RC1:1.3.6.1
	TIGRIS_1_0_5:1.3
	TIGRIS_1_0_5RC6:1.3
	TIGRIS_1_0_5RC5:1.3
	TIGRIS_1_0_5RC4:1.3
	TIGRIS_1_0_5RC3:1.3
	TIGRIS_1_0_5RC2:1.3
	TIGRIS_1_0_5RC1:1.3
	TIGRIS_1_0_4:1.3
	TIGRIS_1_0_3:1.3
	TIGRIS_1_0_2:1.3
	TIGRIS_1_0_1:1.3
	TIGRIS_1_0:1.3.0.6
	TIGRIS_1_0_0:1.3
	TIGRIS_1_0_0_RC1:1.3.0.2;
locks; strict;
comment	@# @;


1.28
date	2001.08.17.21.30.53;	author leonardr;	state Exp;
branches;
next	1.27;

1.27
date	2001.08.11.09.08.02;	author dlr;	state Exp;
branches;
next	1.26;

1.26
date	2001.08.03.17.52.28;	author dlr;	state Exp;
branches;
next	1.25;

1.25
date	2001.08.03.01.59.11;	author dlr;	state Exp;
branches;
next	1.24;

1.24
date	2001.08.03.01.58.56;	author dlr;	state Exp;
branches;
next	1.23;

1.23
date	2001.07.16.19.05.39;	author dlr;	state Exp;
branches;
next	1.22;

1.22
date	2001.07.12.00.43.58;	author leonardr;	state Exp;
branches;
next	1.21;

1.21
date	2001.07.11.22.00.17;	author leonardr;	state Exp;
branches;
next	1.20;

1.20
date	2001.07.11.17.38.15;	author leonardr;	state Exp;
branches;
next	1.19;

1.19
date	2001.06.12.23.10.43;	author leonardr;	state Exp;
branches;
next	1.18;

1.18
date	2001.06.08.17.18.16;	author leonardr;	state Exp;
branches;
next	1.17;

1.17
date	2001.05.23.01.50.13;	author dlr;	state Exp;
branches;
next	1.16;

1.16
date	2001.05.22.00.14.19;	author leonardr;	state Exp;
branches;
next	1.15;

1.15
date	2001.05.21.20.35.06;	author leonardr;	state Exp;
branches;
next	1.14;

1.14
date	2001.05.17.17.10.23;	author dlr;	state Exp;
branches;
next	1.13;

1.13
date	2001.05.17.14.51.16;	author leonardr;	state Exp;
branches;
next	1.12;

1.12
date	2001.05.17.00.28.35;	author dlr;	state Exp;
branches;
next	1.11;

1.11
date	2001.05.09.18.28.23;	author leonardr;	state Exp;
branches;
next	1.10;

1.10
date	2001.05.03.19.44.18;	author dlr;	state Exp;
branches;
next	1.9;

1.9
date	2001.05.02.06.53.39;	author dlr;	state Exp;
branches;
next	1.8;

1.8
date	2001.04.20.22.26.27;	author leonardr;	state Exp;
branches;
next	1.7;

1.7
date	2001.04.20.21.19.40;	author leonardr;	state Exp;
branches;
next	1.6;

1.6
date	2001.04.20.15.30.21;	author dlr;	state Exp;
branches;
next	1.5;

1.5
date	2001.04.12.20.28.32;	author dlr;	state Exp;
branches;
next	1.4;

1.4
date	2001.04.12.18.49.00;	author leonardr;	state Exp;
branches;
next	1.3;

1.3
date	2001.03.09.22.37.55;	author leonardr;	state Exp;
branches
	1.3.6.1;
next	1.2;

1.2
date	2001.03.07.02.33.16;	author dlr;	state Exp;
branches;
next	1.1;

1.1
date	2001.03.07.01.13.15;	author lucas;	state Exp;
branches;
next	;

1.3.6.1
date	2001.06.01.19.18.07;	author leonardr;	state Exp;
branches;
next	;


desc
@@


1.28
log
@Gated debug statements.
@
text
@/* ================================================================ * Copyright (c) 2001 CollabNet.  All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 
 * 3. The end-user documentation included with the redistribution, if
 * any, must include the following acknowlegement: "This product includes
 * software developed by CollabNet (http://www.collab.net/)."
 * Alternately, this acknowlegement may appear in the software itself, if
 * and wherever such third-party acknowlegements normally appear.
 * 
 * 4. The hosted project names must not be used to endorse or promote
 * products derived from this software without prior written
 * permission. For written permission, please contact info@@collab.net.
 * 
 * 5. Products derived from this software may not use the "Tigris" name
 * nor may "Tigris" appear in their names without prior written
 * permission of CollabNet.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL COLLABNET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ====================================================================
 * 
 * This software consists of voluntary contributions made by many
 * individuals on behalf of CollabNet.
 */

package org.tigris.helm.om;

import java.util.*;
import java.io.Serializable;

import com.workingdogs.village.Record;

import org.apache.commons.util.exception.NestableException;
import org.apache.torque.adapter.DBOracle;
import org.apache.torque.util.Criteria;
import org.apache.torque.util.BasePeer;
import org.apache.torque.pool.DBConnection;
import org.apache.fulcrum.db.TurbineDB;
import org.apache.turbine.util.Log;

import org.tigris.helm.tool.cache.*;

/** 
 * The base Helm peer. Stuff that all Helm peers should implement
 * should go here.
 *
 * @@author <a href="mailto:leonardr@@collab.net">Leonard Richardson</a>
 */
public class HelmPeer extends BasePeer
{
    /**
     * Flag for debug messages.
     */
    protected static boolean DEBUG = false;

    /**
     * The Turbine name of the Helm database.
     */
    public static final String DATABASE_NAME = "default";

    /**
     * Fields filterable for pagination.  Overshadowed by any
     * <code>filterableFields</code> member defined in sub classes.
     */
    public static Map filterableFields = new HashMap(0);

    /**
     * The default <code>ORDER BY</code> used by pagination.
     */
    public static final String DEFAULT_ORDER_BY = null;

    /**
     * Whether or not objects of this type should be ordered ascending.
     */
    public static final Boolean ORDER_ASCENDING = Boolean.TRUE;

    /**
     * An empty set of criteria to use in database queries where all
     * results from a table are desired.
     */
    public static final Criteria NO_CRITERIA = new Criteria(0);

    /**
     * Returns the number of entries in the given table.
     */
    public static int numberOfRecords(String tableName)
        throws Exception
    {
        String query = "select count(*) from " + tableName;
        Vector recs = executeQuery(query);
        Record r = (Record)recs.get(0);
        return r.getValue(1).asInt();
    }

    /**
     * Returns true iff this site is running off an Oracle database.
     */
    protected static boolean isOracle()
        throws Exception
    {
        return (TurbineDB.getDB() instanceof DBOracle);
    }

    /**
     * Returns the string put into a SQL query for this database
     * to get the current time.
     */
    protected static String getNowFunction()
        throws Exception
    {
        String function = "NOW()";
        if (isOracle())
        {
            function = "sysdate";
        }
        return function;
    }

    /**
     * Locks the given arrays of tables for reading and writing,
     * respectively.
     */
    public static DBConnection lockTables(String[] readNames, 
                                          String[] writeNames)
        throws Exception
    {        
        StringBuffer query = new StringBuffer();
        if (isOracle())
        {
            query.append("select 'lock' from ");
        }
        else
        {
            query.append("lock tables ");
        }
        
        for (int i = 0; i < readNames.length; i++)
        {
            query.append(readNames[i]);
            if (!isOracle())
            {
                query.append(" read");
            }
            if (i < readNames.length-1)
            {
                query.append(", ");
            }
        }
            
        if (readNames.length > 0 && writeNames.length > 0)
        {
            query.append(", ");
        }

        for (int i = 0; i < writeNames.length; i++)
        {
            query.append(writeNames[i]);
            if (!isOracle())
            {
                query.append(" write");
            }
            if (i < writeNames.length-1)
            {
                query.append(", ");
            }
        }

        if (isOracle())
        {
            query.append(" for update");
        }
       
        DBConnection connection = beginTransaction(DATABASE_NAME);
        executeStatement(query.toString(), connection);
        return connection;
    }

    /**
     * Unlocks all currently locked tables.
     */
    public static void unlockTables(DBConnection connection)
        throws Exception
    {
        if (!isOracle())
        {
            executeStatement("unlock tables", connection);
        }
        commitTransaction(connection);
    }

    /**
     * Generic cache invalidation method for occasions when it is
     * known which object has changed.  
     */
    public static void uncache(HelmObject object)
        throws Exception
    {
        String source = CacheRegistryService.ALL_CACHES_DESCRIPTOR;
        if (object != null)
        {
            source = object.getClass().getName();
        }
        if (DEBUG)
        {
            Log.debug("A particular object of class " + source
                      + " was changed.");
        }
        CacheRegistryService.getService().invalidate(source);
    }

    /**
     * Generic cache invalidation method for occasions when it is not
     * known which object(s) changed, but the class of the Object
     * is known.  
     */
    public static void uncache(Class objectClass)
        throws Exception
    {
        String source = CacheRegistryService.ALL_CACHES_DESCRIPTOR;
        if (objectClass != null)
        {
            String objectName = objectClass.getName();
            if (DEBUG)
            {
                Log.debug("Some object(s) of class " + objectName
                          + " were changed, but I don't know which one(s).");
            }
            source = objectName;
        }
        
        CacheRegistryService.getService().invalidate(source);
    }
}
@


1.27
log
@Upgrading to Turbine 3.0-dev, Fulcrum 1.0, and Torque 1.0.
@
text
@d74 1
a74 1
    protected static boolean DEBUG = true;
d223 5
a227 1
        Log.debug("A particular object of class " + source + " was changed.");
d243 5
a247 2
            Log.debug("Some object(s) of class " + objectName
                      + " were changed, but I don't know which one(s).");
@


1.26
log
@Tweaked member variable attributes.
@
text
@d51 1
a51 1
import com.workingdogs.village.*;
d53 6
a58 4
import org.apache.turbine.om.*;
import org.apache.turbine.om.peer.*;
import org.apache.turbine.util.db.Criteria;
import org.apache.turbine.util.db.pool.DBConnection;
a59 3
import org.apache.turbine.util.TurbineException;
import org.apache.turbine.services.db.TurbineDB;
import org.apache.turbine.util.db.adapter.DBOracle;
a245 1

@


1.25
log
@DEBUG variables should always be static final.
@
text
@d75 1
a75 1
    public static final boolean DEBUG = true;
@


1.24
log
@Used appropriate constant.
@
text
@d75 1
a75 1
    public static boolean DEBUG = true;
@


1.23
log
@Used parens to denote evaluation.
@
text
@a58 1

d219 1
a219 1
        String source = "*";
d236 1
a236 1
        String source = "*";
@


1.22
log
@A little knowledge is a dangerous thing.
@
text
@d123 1
a123 1
        return TurbineDB.getDB() instanceof DBOracle;
@


1.21
log
@Made generated SQL database-independant, for 'database-independant' == 'works on both MySQL and Oracle'
@
text
@d152 1
a152 1
            query.append("select next_id from ");
@


1.20
log
@More action cleanup, and reinstated Domain - View action because it turns out to have been in use after all.
@
text
@d146 1
a146 1
                                        String[] writeNames)
d158 1
a158 1

@


1.19
log
@PeerBackedList performance boost and refactoring. This may be more complicated than it needs to be; rather than getting ever-increasing proportions of the table, it might be faster in most cases to get the whole table, so long as you stop processing results when the list is full enough.
@
text
@d59 3
a61 1
import org.apache.turbine.util.TurbineException;
d118 24
d148 11
a158 2
    {
        StringBuffer query = new StringBuffer("lock tables ");
d161 5
a165 1
            query.append(readNames[i]).append(" read");
d171 1
a171 1

d179 5
a183 1
            query.append(writeNames[i]).append(" write");
d190 5
d206 4
a209 1
        executeStatement("unlock tables", connection);
@


1.18
log
@Added general records-in-table method.
@
text
@d93 5
@


1.17
log
@Ported Helm from WebMacro to Velocity.
@
text
@d51 2
d99 12
d192 1
@


1.16
log
@Bug fixes for clustering.
@
text
@d56 2
@


1.15
log
@Added method to do a select count.
@
text
@a48 1
import java.rmi.RemoteException;
a56 2
import com.workingdogs.village.*;

a92 12

    /**
     * Returns the number of items in this table.
     */
    public static int itemsInTable()
        throws Exception
    {
        String query = "select count(*) from " + TABLE_NAME;
        Vector results = executeQuery(query);
        Record r = (Record)results.get(0);
        return r.getValue(0).asInt();
    }
@


1.14
log
@Reverting portion of Leonard's last commit where he accidently removed
the code which actually retrieves the transactional database connection.
@
text
@d58 2
a59 1
import org.tigris.helm.tool.cluster.ClusterObject;
d98 12
d161 1
a161 1
        throws RemoteException
d163 1
a163 1
        Serializable source = Boolean.FALSE;
d169 1
a169 2
        CacheRegistry.getService().sendEvent
            (new CacheInvalidationEvent(source, null));
d174 1
a174 1
     * known which object(s) changed, but the class of the Peer used
d177 2
a178 2
    public static void uncache(Class peerClass)
        throws RemoteException
d180 2
a181 2
        Serializable source = Boolean.FALSE;
        if (peerClass != null)
d183 2
a184 3
            String className = peerClass.getName();
            className = className.substring(0,className.length()-4);
            Log.debug("Some object(s) of class " + className 
d186 1
a186 1
            source = className;
d189 1
a189 2
        CacheRegistry.getService().sendEvent
            (new CacheInvalidationEvent(source, null));
@


1.13
log
@Refactored a lot of code to get rid of the good-looking but very slow IssueTrackingAccount{Descriptor,Map} classes. Also cleaned up the script-running interface quite a bit.
@
text
@d127 2
a128 3
        
        DBConnection connection = null;
        connection = beginTransaction(DATABASE_NAME);
@


1.12
log
@Sync'd with changes to Turbine BasePeer API.
@
text
@d129 1
a129 10
        try
        {
            connection = beginTransaction(DATABASE_NAME);
        }
        catch (Exception e)
        {
            Log.error("", e);
            throw e;
        }

@


1.11
log
@Added helper methods to lock and unlock tables.
@
text
@d139 1
a139 1
        executeStatement(query.toString(), DATABASE_NAME, connection);
d149 1
a149 1
        executeStatement("unlock tables", DATABASE_NAME, connection);
@


1.10
log
@Spruced up filterableFields class member.
@
text
@d1 1
a1 2
/* ================================================================
 * Copyright (c) 2001 CollabNet.  All rights reserved.
d55 1
d75 5
d94 58
a151 1
    protected static final Criteria NO_CRITERIA = new Criteria(0);
@


1.9
log
@Added an empty set of criteria to use in database queries where all
results from a table are desired.
@
text
@d75 2
a76 1
     * Fields filterable for pagination.
d78 1
a78 1
    public static Map filterableFields = new HashMap();
@


1.8
log
@Corrected off-by-one error.
@
text
@d85 6
@


1.7
log
@Send CacheInvalidationEvents on deletes, and on saves of objects which are not themselves cached but which invalidate other caches when they are changed.
@
text
@d113 1
a113 1
            className = className.substring(0,className.length()-3);
@


1.6
log
@Added semi-selective cache invalidation which invalidates particular caches on a write instead of all the caches.
@
text
@d85 2
a86 1
     * Generic cache invalidation method.
d95 22
@


1.5
log
@Renamed local reference in uncache(HelmObject) to reflect what is
actually represents.
@
text
@d51 1
d70 5
d90 2
a91 2
        Object source = object;
        if (object == null)
d93 1
a93 1
            source = Boolean.FALSE;
@


1.4
log
@Caching fixes and additions.
@
text
@d84 1
a84 1
        Object descriptor = object;
d87 1
a87 1
            descriptor = Boolean.FALSE;
d91 1
a91 1
            (new CacheInvalidationEvent(descriptor, null));
@


1.3
log
@Default order is not to order at all.
@
text
@d50 1
d57 3
d77 16
@


1.3.6.1
log
@Ported minimal cluster functionality so that I could also port IssueTrackingRebuildService, which builds on it.
@
text
@a53 1
import org.apache.turbine.util.db.pool.DBConnection;
a63 6

    /**
     * The Turbine name of the Helm database.
     */
    public static final String DATABASE_NAME = "default";

a72 48

    /**
     * Locks the given arrays of tables for reading and writing,
     * respectively.
     */
    public static DBConnection lockTables(String[] readNames, 
                                        String[] writeNames)
        throws Exception
    {
        StringBuffer query = new StringBuffer("lock tables ");
        for (int i = 0; i < readNames.length; i++)
        {
            query.append(readNames[i]).append(" read");
            if (i < readNames.length-1)
            {
                query.append(", ");
            }
        }

        if (readNames.length > 0 && writeNames.length > 0)
        {
            query.append(", ");
        }

        for (int i = 0; i < writeNames.length; i++)
        {
            query.append(writeNames[i]).append(" write");
            if (i < writeNames.length-1)
            {
                query.append(", ");
            }
        }

        DBConnection connection = beginTransaction(DATABASE_NAME);
        executeStatement(query.toString(), DATABASE_NAME, connection);
        return connection;
    }

    /**
     * Unlocks all currently locked tables.
     */
    public static void unlockTables(DBConnection connection)
        throws Exception
    {
        executeStatement("unlock tables", DATABASE_NAME, connection);
        commitTransaction(connection);
    }

@


1.2
log
@Added JavaDoc.
@
text
@d72 1
a72 1
    public static final String DEFAULT_ORDER_BY = "";    
@


1.1
log
@Moved in from peer package to handle Torque changes. -dlr
@
text
@d64 4
d69 3
a71 2
    //Fields for user pagination.
    public static Map filterableFields = new HashMap();
a72 1

@

