mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-15 15:02:20 +00:00
Merged 5.0.N (5.0.4) to 5.1.N (5.1.2)
124539 jvonka: Merged 50N-NDB (5.0.4) to 5.0.N (5.0.4) 124514: MNT-15211: NDB-specific workaround fix for trashcan restore (since NDB does not support partial rollback on constraint violation) - this fix is dialect-specific (hence does not impact existing supported DB types) - note: MySQL Cluster NDB - experimental/unsupported git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.1.N/root@124582 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -145,6 +145,9 @@
|
||||
<bean id="nodeDAO.org.hibernate.dialect.MySQLInnoDBDialect" class="org.alfresco.repo.domain.node.ibatis.NodeDAOImpl$MySQL" parent="nodeDAO.org.hibernate.dialect.Dialect" />
|
||||
<bean id="nodeDAO.org.alfresco.repo.domain.hibernate.dialect.AlfrescoSQLServerDialect" class="org.alfresco.repo.domain.node.ibatis.NodeDAOImpl$MSSQL" parent="nodeDAO.org.hibernate.dialect.Dialect" />
|
||||
|
||||
<!-- WARNING: Experimental/unsupported - see AlfrescoMySQLClusterNDBDialect ! -->
|
||||
<bean id="nodeDAO.org.alfresco.repo.domain.hibernate.dialect.AlfrescoMySQLClusterNDBDialect" class="org.alfresco.repo.domain.node.ibatis.NodeDAOImpl$MySQLClusterNDB" parent="nodeDAO.org.hibernate.dialect.Dialect" />
|
||||
|
||||
<bean id="lockDAO" class="org.alfresco.repo.domain.locks.ibatis.LockDAOImpl">
|
||||
<property name="sqlSessionTemplate" ref="locksSqlSessionTemplate"/>
|
||||
<property name="qnameDAO" ref="qnameDAO"/>
|
||||
|
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2016 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.domain.hibernate.dialect;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.hibernate.dialect.MySQLInnoDBDialect;
|
||||
|
||||
/**
|
||||
* MySQL Cluster NDB specific DAO overrides
|
||||
*
|
||||
* WARNING:
|
||||
* - Experimental only (unsupported) !
|
||||
* - The NDB storage engine is *not* currently supported or certified !
|
||||
* - Can be used for dev/test evaluation (please give us feedback)
|
||||
* - Should not be used for live/prod env with real data !
|
||||
* - Requires FK support (hence NDB 7.3.x or higher)
|
||||
*
|
||||
* @author janv
|
||||
*
|
||||
*/
|
||||
//note: *not* a dialect of InnoDB but, for now, extends here so that we can override those scripts
|
||||
public class AlfrescoMySQLClusterNDBDialect extends MySQLInnoDBDialect
|
||||
{
|
||||
protected Log logger = LogFactory.getLog(AlfrescoMySQLClusterNDBDialect.class);
|
||||
|
||||
public AlfrescoMySQLClusterNDBDialect()
|
||||
{
|
||||
super();
|
||||
|
||||
logger.error("Using NDB with Alfresco is experimental and unsupported (do not use for live/prod envs) !");
|
||||
}
|
||||
|
||||
public String getTableTypeString() {
|
||||
return " engine=NDB";
|
||||
}
|
||||
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2013 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2016 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
@@ -1390,6 +1390,37 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
|
||||
|
||||
if (!allowAuditableAspect) addAuditableAspect = false;
|
||||
|
||||
Long id = newNodeImplInsert(node);
|
||||
node.setId(id);
|
||||
|
||||
Set<QName> nodeAspects = null;
|
||||
if (addAuditableAspect)
|
||||
{
|
||||
Long auditableAspectQNameId = qnameDAO.getOrCreateQName(ContentModel.ASPECT_AUDITABLE).getFirst();
|
||||
insertNodeAspect(id, auditableAspectQNameId);
|
||||
nodeAspects = Collections.<QName>singleton(ContentModel.ASPECT_AUDITABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeAspects = Collections.<QName>emptySet();
|
||||
}
|
||||
|
||||
// Lock the node and cache
|
||||
node.lock();
|
||||
nodesCache.setValue(id, node);
|
||||
// Pre-populate some of the other caches so that we don't immediately query
|
||||
setNodeAspectsCached(id, nodeAspects);
|
||||
setNodePropertiesCached(id, Collections.<QName, Serializable>emptyMap());
|
||||
|
||||
if (isDebugEnabled)
|
||||
{
|
||||
logger.debug("Created new node: \n" + " " + node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
protected Long newNodeImplInsert(NodeEntity node)
|
||||
{
|
||||
Long id = null;
|
||||
Savepoint savepoint = controlDAO.createSavepoint("newNodeImpl");
|
||||
try
|
||||
@@ -1425,32 +1456,8 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
|
||||
throw new NodeExistsException(dbTargetNode.getNodePair(), e);
|
||||
}
|
||||
}
|
||||
node.setId(id);
|
||||
|
||||
Set<QName> nodeAspects = null;
|
||||
if (addAuditableAspect)
|
||||
{
|
||||
Long auditableAspectQNameId = qnameDAO.getOrCreateQName(ContentModel.ASPECT_AUDITABLE).getFirst();
|
||||
insertNodeAspect(id, auditableAspectQNameId);
|
||||
nodeAspects = Collections.<QName>singleton(ContentModel.ASPECT_AUDITABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeAspects = Collections.<QName>emptySet();
|
||||
}
|
||||
|
||||
// Lock the node and cache
|
||||
node.lock();
|
||||
nodesCache.setValue(id, node);
|
||||
// Pre-populate some of the other caches so that we don't immediately query
|
||||
setNodeAspectsCached(id, nodeAspects);
|
||||
setNodePropertiesCached(id, Collections.<QName, Serializable>emptyMap());
|
||||
|
||||
if (isDebugEnabled)
|
||||
{
|
||||
logger.debug("Created new node: \n" + " " + node);
|
||||
}
|
||||
return node;
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2016 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
@@ -28,6 +28,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.ibatis.IdsEntity;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.domain.node.AbstractNodeDAOImpl;
|
||||
@@ -37,6 +38,7 @@ import org.alfresco.repo.domain.node.Node;
|
||||
import org.alfresco.repo.domain.node.NodeAspectsEntity;
|
||||
import org.alfresco.repo.domain.node.NodeAssocEntity;
|
||||
import org.alfresco.repo.domain.node.NodeEntity;
|
||||
import org.alfresco.repo.domain.node.NodeExistsException;
|
||||
import org.alfresco.repo.domain.node.NodeIdAndAclId;
|
||||
import org.alfresco.repo.domain.node.NodePropertyEntity;
|
||||
import org.alfresco.repo.domain.node.NodePropertyKey;
|
||||
@@ -1719,7 +1721,7 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* MySQL-specific DAO overrides
|
||||
* MySQL (InnoDB) specific DAO overrides
|
||||
*/
|
||||
public static class MySQL extends NodeDAOImpl
|
||||
{
|
||||
@@ -1744,6 +1746,58 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MySQL Cluster NDB specific DAO overrides
|
||||
*
|
||||
* WARNING: Experimental/unsupported - see AlfrescoMySQLClusterNDBDialect !
|
||||
*
|
||||
* @author janv
|
||||
*/
|
||||
public static class MySQLClusterNDB extends MySQL
|
||||
{
|
||||
@Override
|
||||
protected Long newNodeImplInsert(NodeEntity node)
|
||||
{
|
||||
Long id = null;
|
||||
try
|
||||
{
|
||||
// We need to handle existing deleted nodes.
|
||||
NodeRef targetNodeRef = node.getNodeRef();
|
||||
Node dbTargetNode = selectNodeByNodeRef(targetNodeRef);
|
||||
if (dbTargetNode != null)
|
||||
{
|
||||
if (dbTargetNode.getDeleted(qnameDAO))
|
||||
{
|
||||
Long dbTargetNodeId = dbTargetNode.getId();
|
||||
// This is OK. It happens when we create a node that existed in the past.
|
||||
// Remove the row completely
|
||||
deleteNodeProperties(dbTargetNodeId, (Set<Long>) null);
|
||||
deleteNodeById(dbTargetNodeId);
|
||||
}
|
||||
else
|
||||
{
|
||||
// A live node exists.
|
||||
throw new NodeExistsException(dbTargetNode.getNodePair(), null);
|
||||
}
|
||||
}
|
||||
|
||||
id = insertNode(node);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (e instanceof NodeExistsException)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
|
||||
// There does not appear to be any row that could prevent an insert
|
||||
throw new AlfrescoRuntimeException("Failed to insert new node: " + node, e);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get most recent transaction made in a given commit time range
|
||||
*/
|
||||
|
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||
|
||||
* Copyright (C) 2005-2016 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
@@ -70,6 +69,7 @@ import org.alfresco.repo.admin.patch.AppliedPatch;
|
||||
import org.alfresco.repo.admin.patch.Patch;
|
||||
import org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch;
|
||||
import org.alfresco.repo.content.filestore.FileContentWriter;
|
||||
import org.alfresco.repo.domain.hibernate.dialect.AlfrescoMySQLClusterNDBDialect;
|
||||
import org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect;
|
||||
import org.alfresco.repo.domain.hibernate.dialect.AlfrescoSQLServerDialect;
|
||||
import org.alfresco.repo.domain.hibernate.dialect.AlfrescoSybaseAnywhereDialect;
|
||||
@@ -1478,6 +1478,23 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
||||
sql = sql.replaceAll("(?i)TYPE=InnoDB", "ENGINE=InnoDB");
|
||||
}
|
||||
|
||||
if (this.dialect != null && this.dialect instanceof AlfrescoMySQLClusterNDBDialect)
|
||||
{
|
||||
// note: enable bootstrap on MySQL Cluster NDB
|
||||
/*
|
||||
* WARNING: Experimental/unsupported - see AlfrescoMySQLClusterNDBDialect !
|
||||
*/
|
||||
sql = sql.replaceAll("(?i)TYPE=InnoDB", "ENGINE=NDB"); // belts-and-braces
|
||||
sql = sql.replaceAll("(?i)ENGINE=InnoDB", "ENGINE=NDB");
|
||||
|
||||
sql = sql.replaceAll("(?i) BIT ", " BOOLEAN ");
|
||||
sql = sql.replaceAll("(?i) BIT,", " BOOLEAN,");
|
||||
|
||||
sql = sql.replaceAll("(?i) string_value text", " string_value VARCHAR(1024)");
|
||||
|
||||
sql = sql.replaceAll("(?i) VARCHAR(4000)", "TEXT(4000)");
|
||||
}
|
||||
|
||||
Object fetchedVal = executeStatement(connection, sql, fetchColumnName, optional, line, scriptFile);
|
||||
if (fetchVarName != null && fetchColumnName != null)
|
||||
{
|
||||
@@ -1635,6 +1652,12 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
||||
// serializable_value blob,
|
||||
maxStringLength = Integer.MAX_VALUE;
|
||||
}
|
||||
else if (dialect instanceof AlfrescoMySQLClusterNDBDialect)
|
||||
{
|
||||
// string_value varchar(1024),
|
||||
// serializable_value blob,
|
||||
maxStringLength = SchemaBootstrap.DEFAULT_MAX_STRING_LENGTH;
|
||||
}
|
||||
else if (dialect instanceof AlfrescoOracle9Dialect)
|
||||
{
|
||||
// string_value varchar2(1024 char),
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2016 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
@@ -35,6 +35,7 @@ import javax.sql.DataSource;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.content.filestore.FileContentWriter;
|
||||
import org.alfresco.repo.domain.hibernate.dialect.AlfrescoMySQLClusterNDBDialect;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.util.LogUtil;
|
||||
import org.alfresco.util.TempFileProvider;
|
||||
@@ -537,6 +538,23 @@ public class ScriptExecutorImpl implements ScriptExecutor
|
||||
sql = sql.replaceAll("(?i)TYPE=InnoDB", "ENGINE=InnoDB");
|
||||
}
|
||||
|
||||
if (this.dialect != null && this.dialect instanceof AlfrescoMySQLClusterNDBDialect)
|
||||
{
|
||||
// note: enable bootstrap on MySQL Cluster NDB
|
||||
/*
|
||||
* WARNING: Experimental/unsupported - see AlfrescoMySQLClusterNDBDialect !
|
||||
*/
|
||||
sql = sql.replaceAll("(?i)TYPE=InnoDB", "ENGINE=NDB"); // belts-and-braces
|
||||
sql = sql.replaceAll("(?i)ENGINE=InnoDB", "ENGINE=NDB");
|
||||
|
||||
sql = sql.replaceAll("(?i) BIT ", " BOOLEAN ");
|
||||
sql = sql.replaceAll("(?i) BIT,", " BOOLEAN,");
|
||||
|
||||
sql = sql.replaceAll("(?i) string_value text", " string_value VARCHAR(1024)");
|
||||
|
||||
sql = sql.replaceAll("(?i) VARCHAR(4000)", "TEXT(4000)");
|
||||
}
|
||||
|
||||
Object fetchedVal = executeStatement(connection, sql, fetchColumnName, optional, line, scriptFile);
|
||||
if (fetchVarName != null && fetchColumnName != null)
|
||||
{
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2016 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
@@ -916,6 +916,8 @@ public class ArchiveAndRestoreTest extends TestCase
|
||||
RestoreNodeReport report = nodeArchiveService.restoreArchivedNode(r_);
|
||||
assertEquals("Restore failed", RestoreStatus.SUCCESS, report.getStatus());
|
||||
|
||||
commitAndBeginNewTransaction();
|
||||
|
||||
//It is restored, still with no AUDITABLE ASPECT
|
||||
verifyNodeExistence(r, true);
|
||||
verifyAspectExistence(r, ContentModel.ASPECT_AUDITABLE, false);
|
||||
|
Reference in New Issue
Block a user