new ArrayList<AttributeType>();
boolean extensibleObject = false;
// Update ocs tables.
NdbTransaction ndbDATxn = null;
for (Map.Entry<ObjectClass, String> ocEntry : ocMap.entrySet()) {
ObjectClass oc = ocEntry.getKey();
String ocName = oc.getNameOrOID();
Map<Integer, NdbOperation> mvOpMap =
new HashMap<Integer, NdbOperation>();
if (nClasses > 0) {
ocBuffer.append(" ");
}
ocBuffer.append(ocName);
nClasses++;
if (oc.getObjectClassType() == ObjectClassType.ABSTRACT) {
continue;
}
if (ocName.equalsIgnoreCase(OC_EXTENSIBLEOBJECT)) {
extensibleObject = true;
}
if (ndbDATxn == null) {
ndbDATxn = txn.getNdbDATransaction(ocName, id);
}
if (overwrite) {
op = ndbDATxn.getWriteOperation(ocName);
} else {
op = ndbDATxn.getInsertOperation(ocName);
}
op.equalLong(BackendImpl.EID, id);
op.equalInt(BackendImpl.MID, MIN_MID);
mvOpMap.put(MIN_MID, op);
for (AttributeType reqAttr : oc.getRequiredAttributes()) {
if (userAttributes.contains(reqAttr)) {
continue;
}
if (reqAttr.isOperational()) {
userAttrMap.put(reqAttr, entry.getOperationalAttribute(reqAttr));
}
String attrName = reqAttr.getNameOrOID();
if (entry.hasAttribute(reqAttr)) {
boolean indexed = BackendImpl.indexes.contains(attrName);
List<Attribute> attrList = userAttrMap.get(reqAttr);
int mid = MIN_MID;
for (Attribute attr : attrList) {
if (attr.isVirtual() || attr.isEmpty()) {
continue;
}
// Attribute options.
Set<String> attrOptionsSet = attr.getOptions();
if (!attrOptionsSet.isEmpty()) {
if (overwrite) {
tagOp =
ndbDATxn.getWriteOperation(BackendImpl.TAGS_TABLE);
} else {
tagOp =
ndbDATxn.getInsertOperation(BackendImpl.TAGS_TABLE);
}
tagOp.equalLong(BackendImpl.EID, id);
tagOp.equalString(BackendImpl.TAG_ATTR, attrName);
tagOp.equalInt(BackendImpl.MID, mid);
StringBuilder buffer = new StringBuilder();
for (String option : attrOptionsSet) {
buffer.append(';');
buffer.append(option);
}
tagOp.setString(BackendImpl.TAG_TAGS, buffer.toString());
}
for (AttributeValue attrVal : attr) {
String attrStringVal = attrVal.toString();
NdbOperation attrOp = mvOpMap.get(mid);
if (attrOp == null) {
if (overwrite) {
attrOp = ndbDATxn.getWriteOperation(ocName);
} else {
attrOp = ndbDATxn.getInsertOperation(ocName);
}
attrOp.equalLong(BackendImpl.EID, id);
attrOp.equalInt(BackendImpl.MID, mid);
mvOpMap.put(mid, attrOp);
}
if (BackendImpl.blobAttributes.contains(attrName)) {
NdbBlob blob = attrOp.getBlobHandle(attrName);
blob.setValue(new byte[0]);
byte[] blobBytes = attrVal.getValue().toByteArray();
blobMap.put(blob, blobBytes);
} else {
attrOp.setString(attrName, attrStringVal);
}
// Update Indexes.
if (indexed) {
NdbOperation idxOp = null;
if (overwrite) {
idxOp = ndbDATxn.getWriteOperation(
BackendImpl.IDX_TABLE_PREFIX + attrName);
} else {
idxOp = ndbDATxn.getInsertOperation(
BackendImpl.IDX_TABLE_PREFIX + attrName);
}
idxOp.equalLong(BackendImpl.EID, id);
idxOp.equalInt(BackendImpl.MID, mid);
idxOp.setString(BackendImpl.IDX_VAL, attrStringVal);
}
mid++;
}
}
userAttributes.add(reqAttr);
}
}
for (AttributeType optAttr : oc.getOptionalAttributes()) {
if (userAttributes.contains(optAttr)) {
continue;
}
if (optAttr.isOperational()) {
userAttrMap.put(optAttr, entry.getOperationalAttribute(optAttr));
}
String attrName = optAttr.getNameOrOID();
if (entry.hasAttribute(optAttr)) {
boolean indexed = BackendImpl.indexes.contains(attrName);
List<Attribute> attrList = userAttrMap.get(optAttr);
int mid = MIN_MID;
for (Attribute attr : attrList) {
if (attr.isVirtual() || attr.isEmpty()) {
continue;
}
// Attribute options.
Set<String> attrOptionsSet = attr.getOptions();
if (!attrOptionsSet.isEmpty()) {
if (overwrite) {
tagOp =
ndbDATxn.getWriteOperation(BackendImpl.TAGS_TABLE);
} else {
tagOp =
ndbDATxn.getInsertOperation(BackendImpl.TAGS_TABLE);
}
tagOp.equalLong(BackendImpl.EID, id);
tagOp.equalString(BackendImpl.TAG_ATTR, attrName);
tagOp.equalInt(BackendImpl.MID, mid);
StringBuilder buffer = new StringBuilder();
for (String option : attrOptionsSet) {
buffer.append(';');
buffer.append(option);
}
tagOp.setString(BackendImpl.TAG_TAGS, buffer.toString());
}
for (AttributeValue attrVal : attr) {
String attrStringVal = attrVal.toString();
NdbOperation attrOp = mvOpMap.get(mid);
if (attrOp == null) {
if (overwrite) {
attrOp = ndbDATxn.getWriteOperation(ocName);
} else {
attrOp = ndbDATxn.getInsertOperation(ocName);
}
attrOp.equalLong(BackendImpl.EID, id);
attrOp.equalInt(BackendImpl.MID, mid);
mvOpMap.put(mid, attrOp);
}
if (BackendImpl.blobAttributes.contains(attrName)) {
NdbBlob blob = attrOp.getBlobHandle(attrName);
blob.setValue(new byte[0]);
byte[] blobBytes = attrVal.getValue().toByteArray();
blobMap.put(blob, blobBytes);
} else {
attrOp.setString(attrName, attrStringVal);
}
// Update Indexes.
if (indexed) {
NdbOperation idxOp = null;
if (overwrite) {
idxOp = ndbDATxn.getWriteOperation(
BackendImpl.IDX_TABLE_PREFIX + attrName);
} else {
idxOp = ndbDATxn.getInsertOperation(
BackendImpl.IDX_TABLE_PREFIX + attrName);
}
idxOp.equalLong(BackendImpl.EID, id);
idxOp.equalInt(BackendImpl.MID, mid);
idxOp.setString(BackendImpl.IDX_VAL, attrStringVal);
}
mid++;
}
}
userAttributes.add(optAttr);
}
}
}
// Extensible object.
if (extensibleObject) {
int xnClasses = 0;
for (Map.Entry<AttributeType, List<Attribute>> attrEntry :
userAttrMap.entrySet())
{
AttributeType attrType = attrEntry.getKey();
if (!userAttributes.contains(attrType)) {
String attrName = attrType.getNameOrOID();
String ocName = BackendImpl.attr2Oc.get(attrName);
Map<Integer, NdbOperation> mvOpMap =
new HashMap<Integer, NdbOperation>();
boolean indexed = BackendImpl.indexes.contains(attrName);
if (ndbDATxn == null) {
ndbDATxn = txn.getNdbDATransaction(ocName, id);
}
if (overwrite) {
op = ndbDATxn.getWriteOperation(ocName);
} else {
op = ndbDATxn.getInsertOperation(ocName);
}
op.equalLong(BackendImpl.EID, id);
op.equalInt(BackendImpl.MID, MIN_MID);
mvOpMap.put(MIN_MID, op);
List<Attribute> attrList = userAttrMap.get(attrType);
int mid = MIN_MID;
for (Attribute attr : attrList) {
if (attr.isVirtual() || attr.isEmpty()) {
continue;
}
// Attribute options.
Set<String> attrOptionsSet = attr.getOptions();
if (!attrOptionsSet.isEmpty()) {
if (overwrite) {
tagOp =
ndbDATxn.getWriteOperation(BackendImpl.TAGS_TABLE);
} else {
tagOp =
ndbDATxn.getInsertOperation(BackendImpl.TAGS_TABLE);
}
tagOp.equalLong(BackendImpl.EID, id);
tagOp.equalString(BackendImpl.TAG_ATTR, attrName);
tagOp.equalInt(BackendImpl.MID, mid);
StringBuilder buffer = new StringBuilder();
for (String option : attrOptionsSet) {
buffer.append(';');
buffer.append(option);
}
tagOp.setString(BackendImpl.TAG_TAGS, buffer.toString());
}
for (AttributeValue attrVal : attr) {
String attrStringVal = attrVal.toString();
NdbOperation attrOp = mvOpMap.get(mid);
if (attrOp == null) {
if (overwrite) {
attrOp = ndbDATxn.getWriteOperation(ocName);
} else {
attrOp = ndbDATxn.getInsertOperation(ocName);
}
attrOp.equalLong(BackendImpl.EID, id);
attrOp.equalInt(BackendImpl.MID, mid);
mvOpMap.put(mid, attrOp);
}
if (BackendImpl.blobAttributes.contains(attrName)) {
NdbBlob blob = attrOp.getBlobHandle(attrName);
blob.setValue(new byte[0]);
byte[] blobBytes = attrVal.getValue().toByteArray();
blobMap.put(blob, blobBytes);
} else {
attrOp.setString(attrName, attrStringVal);
}
// Update Indexes.
if (indexed) {
NdbOperation idxOp = null;
if (overwrite) {
idxOp = ndbDATxn.getWriteOperation(
BackendImpl.IDX_TABLE_PREFIX + attrName);
} else {
idxOp = ndbDATxn.getInsertOperation(
BackendImpl.IDX_TABLE_PREFIX + attrName);
}
idxOp.equalLong(BackendImpl.EID, id);
idxOp.equalInt(BackendImpl.MID, mid);
idxOp.setString(BackendImpl.IDX_VAL, attrStringVal);
}
mid++;
}
}
userAttributes.add(attrType);
if (xnClasses > 0) {
xocBuffer.append(" ");
}
xocBuffer.append(ocName);
xnClasses++;
}
}
}
// Update operational attributes table.
if (overwrite) {
op = ndbDATxn.getWriteOperation(BackendImpl.OPATTRS_TABLE);
} else {
op = ndbDATxn.getInsertOperation(BackendImpl.OPATTRS_TABLE);
}
op.equalLong(BackendImpl.EID, id);
for (List<Attribute> attrList :
entry.getOperationalAttributes().values())
{
for (Attribute attr : attrList) {
if (attr.isVirtual() || attr.isEmpty()) {
continue;
}
if (userAttrMap.containsKey(attr.getAttributeType())) {
continue;
}
String attrName = attr.getAttributeType().getNameOrOID();
for (AttributeValue attrVal : attr) {
op.setString(attrName, attrVal.toString());
}
}
}
// Move this txn into the active state and write blob data if any.
if (!blobMap.isEmpty()) {
ndbDATxn.execute(ExecType.NoCommit, AbortOption.AbortOnError, true);
Set<Map.Entry<NdbBlob, byte[]>> blobEntrySet = blobMap.entrySet();
for (Map.Entry blobEntry : blobEntrySet) {
NdbBlob blob = (NdbBlob) blobEntry.getKey();
byte[] blobBytes = (byte[]) blobEntry.getValue();
blob.writeData(blobBytes);
}
}
// Update dn2id table.
NdbTransaction ndbTxn = txn.getNdbTransaction();
if (overwrite) {
op = ndbTxn.getWriteOperation(name);
} else {
op = ndbTxn.getInsertOperation(name);
}
int componentIndex = dn.getNumComponents() - 1;
for (int i=0; i < BackendImpl.DN2ID_DN_NC; i++) {
while (componentIndex >= 0) {