/* * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at . * * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT * WARRANTY OF ANY KIND, either express or implied. See the License for the specific * language governing rights and limitations under the License. * * The Original Code is the Venice Web Communities System. * * The Initial Developer of the Original Code is Eric J. Bowersox , * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. * * Contributor(s): */ package com.silverwrist.venice.community; import java.sql.*; import java.util.*; import com.silverwrist.util.*; import com.silverwrist.dynamo.except.*; import com.silverwrist.dynamo.iface.*; import com.silverwrist.venice.CommunityVisibility; import com.silverwrist.venice.SearchMode; public class CommunityManagerOps_mysql extends CommunityManagerOps { /*-------------------------------------------------------------------------------- * Attributes *-------------------------------------------------------------------------------- */ private DBUtilities m_utils; private CommunityOps m_cops = null; /*-------------------------------------------------------------------------------- * Constructor *-------------------------------------------------------------------------------- */ public CommunityManagerOps_mysql(DBConnectionPool pool) { super(pool); m_utils = (DBUtilities)(pool.queryService(DBUtilities.class)); } // end constructor /*-------------------------------------------------------------------------------- * Internal operations *-------------------------------------------------------------------------------- */ private final String preparePropertySearchTerm(SearchMode mode, String term) { StringBuffer buf = new StringBuffer(); if (SearchMode.PREFIX.equals(mode)) buf.append("LIKE '!").append(m_utils.encodeStringWildcards(term)).append("%'"); else if (SearchMode.SUBSTRING.equals(mode)) buf.append("LIKE '!%").append(m_utils.encodeStringWildcards(term)).append("%'"); else if (SearchMode.REGEXP.equals(mode)) { // for regular expressions, if we're matching the start of the string, we have to inlcude the ! prefix buf.append("REGEXP '"); if (term.startsWith("^")) buf.append("^!").append(m_utils.encodeString(term.substring(1))); else buf.append(m_utils.encodeString(term)); buf.append('\''); } // end else if return buf.toString(); } // end preparePropertySearchTerm /*-------------------------------------------------------------------------------- * Overrides from class OpsBase *-------------------------------------------------------------------------------- */ public void dispose() { if (m_cops!=null) { // dispose the subobject m_cops.dispose(); m_cops = null; } // end if m_utils = null; super.dispose(); } // end dispose /*-------------------------------------------------------------------------------- * Abstract implementations from class CommunityManagerOps *-------------------------------------------------------------------------------- */ synchronized CommunityOps getCommunityOps() { if (m_cops==null) m_cops = new CommunityOps_mysql(getPool()); return m_cops; } // end getCommunityOps Map lookupCommunity(int cid) throws DatabaseException { Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { // get a connection conn = getConnection(); // prepare and execute the query stmt = conn.prepareStatement("SELECT member_gid, host_gid, host_uid, aclid, catid, hide_dir, hide_search, name, " + "alias, createdate, lastaccess, lastupdate FROM communities WHERE cid = ?;"); stmt.setInt(1,cid); rs = stmt.executeQuery(); if (!(rs.next())) return null; // create and return the data structure HashMap rc = new HashMap(); rc.put(KEY_CID,new Integer(cid)); rc.put(KEY_MEMBER_GID,new Integer(rs.getInt(1))); rc.put(KEY_HOST_GID,new Integer(rs.getInt(2))); rc.put(KEY_HOST_UID,new Integer(rs.getInt(3))); rc.put(KEY_ACLID,new Integer(rs.getInt(4))); rc.put(KEY_CATID,new Integer(rs.getInt(5))); if (rs.getInt(6)==0) rc.put(KEY_VISIBILITY,CommunityVisibility.SEARCHDIR); else if (rs.getInt(7)==0) rc.put(KEY_VISIBILITY,CommunityVisibility.SEARCHONLY); else rc.put(KEY_VISIBILITY,CommunityVisibility.NONE); rc.put(KEY_NAME,rs.getString(8)); rc.put(KEY_ALIAS,rs.getString(9)); rc.put(KEY_CREATE,m_utils.getDateTime(rs,10)); rc.put(KEY_ACCESS,m_utils.getDateTime(rs,11)); rc.put(KEY_UPDATE,m_utils.getDateTime(rs,12)); return rc; } // end try catch (SQLException e) { // translate to a general DatabaseException throw generalException(e); } // end catch finally { // shut everything down SQLUtils.shutdown(rs); SQLUtils.shutdown(stmt); SQLUtils.shutdown(conn); } // end finally } // end lookupCommunity Map lookupCommunity(String alias) throws DatabaseException { Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { // get a connection conn = getConnection(); // prepare and execute the query stmt = conn.prepareStatement("SELECT cid, member_gid, host_gid, host_uid, aclid, catid, hide_dir, hide_search, " + "name, createdate, lastaccess, lastupdate FROM communities WHERE alias = ?;"); stmt.setString(1,alias); rs = stmt.executeQuery(); if (!(rs.next())) return null; // create and return the data structure HashMap rc = new HashMap(); rc.put(KEY_CID,new Integer(rs.getInt(1))); rc.put(KEY_MEMBER_GID,new Integer(rs.getInt(2))); rc.put(KEY_HOST_GID,new Integer(rs.getInt(3))); rc.put(KEY_HOST_UID,new Integer(rs.getInt(4))); rc.put(KEY_ACLID,new Integer(rs.getInt(5))); rc.put(KEY_CATID,new Integer(rs.getInt(6))); if (rs.getInt(7)==0) rc.put(KEY_VISIBILITY,CommunityVisibility.SEARCHDIR); else if (rs.getInt(8)==0) rc.put(KEY_VISIBILITY,CommunityVisibility.SEARCHONLY); else rc.put(KEY_VISIBILITY,CommunityVisibility.NONE); rc.put(KEY_NAME,rs.getString(9)); rc.put(KEY_ALIAS,alias); rc.put(KEY_CREATE,m_utils.getDateTime(rs,10)); rc.put(KEY_ACCESS,m_utils.getDateTime(rs,11)); rc.put(KEY_UPDATE,m_utils.getDateTime(rs,12)); return rc; } // end try catch (SQLException e) { // translate to a general DatabaseException throw generalException(e); } // end catch finally { // shut everything down SQLUtils.shutdown(rs); SQLUtils.shutdown(stmt); SQLUtils.shutdown(conn); } // end finally } // end lookupCommunity int[] getMemberCommunityIDs(int uid) throws DatabaseException { Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { // get a connection conn = getConnection(); // prepare and execute the statement stmt = conn.prepareStatement("SELECT c.cid FROM communities c, groupmembers g WHERE c.member_gid = g.gid " + "AND g.uid = ? ORDER BY c.name;"); stmt.setInt(1,uid); rs = stmt.executeQuery(); // Since we don't know how many communities we need to allocate slots for, we allocate smaller arrays // in blocks and stash the small blocks in a LinkedList, keeping track of the total size. LinkedList olist = new LinkedList(); int[] current = new int[16]; int curptr = 0; int total = 0; while (rs.next()) { // fill array segments with community IDs if (curptr==16) { // stack the filled array segment and begin a new one olist.addLast(current); curptr = 0; current = new int[16]; } // end if current[curptr++] = rs.getInt(1); total++; } // end while olist.addLast(current); // add last array to list // allocate and copy the return array int rc[] = new int[total]; curptr = 0; while (total>0) { // get each segment and copy it into return array current = (int[])(olist.removeFirst()); int ct = Math.min(current.length,total); System.arraycopy(current,0,rc,curptr,ct); curptr += ct; total -= ct; } // end while olist.clear(); return rc; } // end try catch (SQLException e) { // translate to a general DatabaseException throw generalException(e); } // end catch finally { // shut everything down SQLUtils.shutdown(rs); SQLUtils.shutdown(stmt); SQLUtils.shutdown(conn); } // end finally } // end getMemberCommunityIDs int[] getCommunityIDsInCategory(int catid, boolean show_all, int offset, int count) throws DatabaseException { Connection conn = null; Statement stmt = null; ResultSet rs = null; try { // get a connection conn = getConnection(); // prepare and execute the statement (note that we assemble it in SQL form); StringBuffer sql = new StringBuffer("SELECT cid FROM communities WHERE catid = "); sql.append(catid); if (!show_all) sql.append(" AND hide_dir = 0"); sql.append(" ORDER BY name LIMIT ").append(offset).append(", ").append(count+1).append(';'); stmt = conn.createStatement(); rs = stmt.executeQuery(sql.toString()); // We *know* the maximum number of indexes that can be returned, so allocate a temporary array big // enough to hold them all. int[] tmp = new int[count+1]; int ct = 0; while (rs.next()) tmp[ct++] = rs.getInt(1); // Create the actual return array and fill it. int[] rc = new int[ct]; System.arraycopy(tmp,0,rc,0,ct); return rc; } // end try catch (SQLException e) { // translate to a general DatabaseException throw generalException(e); } // end catch finally { // shut everything down SQLUtils.shutdown(rs); SQLUtils.shutdown(stmt); SQLUtils.shutdown(conn); } // end finally } // end getCommunityIDsInCategory int getNumCommunityIDsInCategory(int catid, boolean show_all) throws DatabaseException { Connection conn = null; Statement stmt = null; ResultSet rs = null; try { // get a connection conn = getConnection(); // prepare and execute the statement (note that we assemble it in SQL form); StringBuffer sql = new StringBuffer("SELECT COUNT(*) FROM communities WHERE catid = "); sql.append(catid); if (!show_all) sql.append(" AND hide_dir = 0"); sql.append(';'); stmt = conn.createStatement(); rs = stmt.executeQuery(sql.toString()); return SQLUtils.getReturnCountInt(rs,1); } // end try catch (SQLException e) { // translate to a general DatabaseException throw generalException(e); } // end catch finally { // shut everything down SQLUtils.shutdown(rs); SQLUtils.shutdown(stmt); SQLUtils.shutdown(conn); } // end finally } // end getNumCommunityIDsInCategory int[] searchProperty(int nsid, String name, SearchMode mode, String term, boolean show_all, int offset, int count) throws DatabaseException { Connection conn = null; Statement stmt = null; ResultSet rs = null; try { // get a connection conn = getConnection(); // prepare and execute a query (note that we assemble it in SQL form) StringBuffer sql = new StringBuffer("SELECT c.cid FROM communities c, commprops p WHERE c.cid = p.cid " + "AND p.nsid = "); sql.append(nsid).append(" AND p.prop_name = '").append(m_utils.encodeString(name)).append("' AND p.prop_value "); sql.append(preparePropertySearchTerm(mode,term)); if (!show_all) sql.append(" AND c.hide_search = 0"); sql.append(" ORDER BY c.name LIMIT ").append(offset).append(", ").append(count+1).append(';'); stmt = conn.createStatement(); rs = stmt.executeQuery(sql.toString()); // We *know* the maximum number of indexes that can be returned, so allocate a temporary array big // enough to hold them all. int[] tmp = new int[count+1]; int ct = 0; while (rs.next()) tmp[ct++] = rs.getInt(1); // Create the actual return array and fill it. int[] rc = new int[ct]; System.arraycopy(tmp,0,rc,0,ct); return rc; } // end try catch (SQLException e) { // translate to a general DatabaseException throw generalException(e); } // end catch finally { // shut everything down SQLUtils.shutdown(rs); SQLUtils.shutdown(stmt); SQLUtils.shutdown(conn); } // end finally } // end searchProperty int searchPropertyCount(int nsid, String name, SearchMode mode, String term, boolean show_all) throws DatabaseException { Connection conn = null; Statement stmt = null; ResultSet rs = null; try { // get a connection conn = getConnection(); // prepare and execute a query (note that we assemble it in SQL form) StringBuffer sql = new StringBuffer("SELECT COUNT(*) FROM communities c, commprops p WHERE c.cid = p.cid " + "AND p.nsid = "); sql.append(nsid).append(" AND p.prop_name = '").append(m_utils.encodeString(name)).append("' AND p.prop_value "); sql.append(preparePropertySearchTerm(mode,term)); if (!show_all) sql.append(" AND c.hide_search = 0"); sql.append(';'); stmt = conn.createStatement(); rs = stmt.executeQuery(sql.toString()); return SQLUtils.getReturnCountInt(rs,1); } // end try catch (SQLException e) { // translate to a general DatabaseException throw generalException(e); } // end catch finally { // shut everything down SQLUtils.shutdown(rs); SQLUtils.shutdown(stmt); SQLUtils.shutdown(conn); } // end finally } // end searchPropertyCount int[] searchName(SearchMode mode, String term, boolean show_all, int offset, int count) throws DatabaseException { Connection conn = null; Statement stmt = null; ResultSet rs = null; try { // get a connection conn = getConnection(); // prepare and execute a query (note that we assemble it in SQL form) StringBuffer sql = new StringBuffer("SELECT cid FROM communities WHERE name "); if (SearchMode.PREFIX.equals(mode)) sql.append("LIKE '").append(m_utils.encodeStringWildcards(term)).append("%'"); else if (SearchMode.SUBSTRING.equals(mode)) sql.append("LIKE '%").append(m_utils.encodeStringWildcards(term)).append("%'"); else if (SearchMode.REGEXP.equals(mode)) sql.append("REGEXP '").append(m_utils.encodeString(term)).append('\''); if (!show_all) sql.append(" AND hide_search = 0"); sql.append(" ORDER BY name LIMIT ").append(offset).append(", ").append(count+1).append(';'); stmt = conn.createStatement(); rs = stmt.executeQuery(sql.toString()); // We *know* the maximum number of indexes that can be returned, so allocate a temporary array big // enough to hold them all. int[] tmp = new int[count+1]; int ct = 0; while (rs.next()) tmp[ct++] = rs.getInt(1); // Create the actual return array and fill it. int[] rc = new int[ct]; System.arraycopy(tmp,0,rc,0,ct); return rc; } // end try catch (SQLException e) { // translate to a general DatabaseException throw generalException(e); } // end catch finally { // shut everything down SQLUtils.shutdown(rs); SQLUtils.shutdown(stmt); SQLUtils.shutdown(conn); } // end finally } // end searchName int searchNameCount(SearchMode mode, String term, boolean show_all) throws DatabaseException { Connection conn = null; Statement stmt = null; ResultSet rs = null; try { // get a connection conn = getConnection(); // prepare and execute a query (note that we assemble it in SQL form) StringBuffer sql = new StringBuffer("SELECT COUNT(*) FROM communities WHERE name "); if (SearchMode.PREFIX.equals(mode)) sql.append("LIKE '").append(m_utils.encodeStringWildcards(term)).append("%'"); else if (SearchMode.SUBSTRING.equals(mode)) sql.append("LIKE '%").append(m_utils.encodeStringWildcards(term)).append("%'"); else if (SearchMode.REGEXP.equals(mode)) sql.append("REGEXP '").append(m_utils.encodeString(term)).append('\''); if (!show_all) sql.append(" AND hide_search = 0"); sql.append(';'); stmt = conn.createStatement(); rs = stmt.executeQuery(sql.toString()); return SQLUtils.getReturnCountInt(rs,1); } // end try catch (SQLException e) { // translate to a general DatabaseException throw generalException(e); } // end catch finally { // shut everything down SQLUtils.shutdown(rs); SQLUtils.shutdown(stmt); SQLUtils.shutdown(conn); } // end finally } // end searchNameCount } // end class CommunityManagerOps_mysql