Skip to content

Commit 8d7ad86

Browse files
Issue orientechnologies#1818 was fixed.
1 parent 6112c27 commit 8d7ad86

22 files changed

Lines changed: 865 additions & 540 deletions

File tree

core/src/main/java/com/orientechnologies/orient/core/config/OStorageConfiguration.java

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,33 +47,37 @@
4747
*/
4848
@SuppressWarnings("serial")
4949
public class OStorageConfiguration implements OSerializableStream {
50-
public static final ORecordId CONFIG_RID = new OImmutableRecordId(0, OClusterPositionFactory.INSTANCE.valueOf(0));
50+
public static final ORecordId CONFIG_RID = new OImmutableRecordId(0,
51+
OClusterPositionFactory.INSTANCE.valueOf(0));
5152

52-
public static final String DEFAULT_CHARSET = "UTF-8";
53+
public static final String DEFAULT_CHARSET = "UTF-8";
5354

54-
public static final int CURRENT_VERSION = 6;
55+
public static final int CURRENT_VERSION = 7;
56+
public static final int CURRENT_STORAGE_VERSION = 10;
5557

56-
public int version = -1;
58+
public int version = -1;
5759
public String name;
5860
public String schemaRecordId;
5961
public String dictionaryRecordId;
6062
public String indexMgrRecordId;
6163

62-
private String localeLanguage = Locale.getDefault().getLanguage();
63-
private String localeCountry = Locale.getDefault().getCountry();
64-
public String dateFormat = "yyyy-MM-dd";
65-
public String dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
66-
private TimeZone timeZone = TimeZone.getDefault();
67-
private String charset = DEFAULT_CHARSET;
64+
private String localeLanguage = Locale.getDefault().getLanguage();
65+
private String localeCountry = Locale.getDefault().getCountry();
66+
public String dateFormat = "yyyy-MM-dd";
67+
public String dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
68+
private TimeZone timeZone = TimeZone.getDefault();
69+
private String charset = DEFAULT_CHARSET;
70+
71+
public int storageVersion;
6872

6973
public OStorageSegmentConfiguration fileTemplate;
7074

71-
public List<OStorageClusterConfiguration> clusters = new ArrayList<OStorageClusterConfiguration>();
72-
public List<OStorageDataConfiguration> dataSegments = new ArrayList<OStorageDataConfiguration>();
75+
public List<OStorageClusterConfiguration> clusters = new ArrayList<OStorageClusterConfiguration>();
76+
public List<OStorageDataConfiguration> dataSegments = new ArrayList<OStorageDataConfiguration>();
7377

74-
public OStorageTxConfiguration txSegment = new OStorageTxConfiguration();
78+
public OStorageTxConfiguration txSegment = new OStorageTxConfiguration();
7579

76-
public List<OStorageEntryConfiguration> properties = new ArrayList<OStorageEntryConfiguration>();
80+
public List<OStorageEntryConfiguration> properties = new ArrayList<OStorageEntryConfiguration>();
7781

7882
private transient Locale localeInstance;
7983
private transient DecimalFormatSymbols unusualSymbols;
@@ -82,6 +86,8 @@ public class OStorageConfiguration implements OSerializableStream {
8286
public OStorageConfiguration(final OStorage iStorage) {
8387
storage = iStorage;
8488
fileTemplate = new OStorageSegmentConfiguration();
89+
90+
storageVersion = CURRENT_STORAGE_VERSION;
8591
}
8692

8793
/**
@@ -260,6 +266,11 @@ else if (clusterType.equals("d")) {
260266
properties.add(new OStorageEntryConfiguration(read(values[index++]), read(values[index++])));
261267
}
262268

269+
if (version >= 7)
270+
storageVersion = Integer.parseInt(read(values[index++]));
271+
else
272+
storageVersion = 9;
273+
263274
return this;
264275
}
265276

@@ -347,6 +358,8 @@ public byte[] toStream() throws OSerializationException {
347358
for (OStorageEntryConfiguration e : properties)
348359
entryToStream(buffer, e);
349360

361+
write(buffer, storageVersion);
362+
350363
// PLAIN: ALLOCATE ENOUGHT SPACE TO REUSE IT EVERY TIME
351364
buffer.append("|");
352365

core/src/main/java/com/orientechnologies/orient/core/db/document/ODatabaseDocumentTx.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.orientechnologies.orient.core.Orient;
2222
import com.orientechnologies.orient.core.db.ODatabaseComplex;
2323
import com.orientechnologies.orient.core.db.ODatabaseRecordWrapperAbstract;
24+
import com.orientechnologies.orient.core.db.record.OCurrentStorageVersions;
2425
import com.orientechnologies.orient.core.db.record.ODatabaseRecordTx;
2526
import com.orientechnologies.orient.core.db.record.ridbag.sbtree.OSBTreeCollectionManager;
2627
import com.orientechnologies.orient.core.exception.OConcurrentModificationException;
@@ -479,4 +480,9 @@ public String getType() {
479480
public OSBTreeCollectionManager getSbTreeCollectionManager() {
480481
return underlying.getSbTreeCollectionManager();
481482
}
483+
484+
@Override
485+
public OCurrentStorageVersions getStorageVersions() {
486+
return underlying.getStorageVersions();
487+
}
482488
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2010-2012 [email protected]
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.orientechnologies.orient.core.db.record;
18+
19+
import com.orientechnologies.orient.core.config.OStorageConfiguration;
20+
21+
/**
22+
* @author Andrey Lomakin <a href="mailto:[email protected]">Andrey Lomakin</a>
23+
* @since 2/14/14
24+
*/
25+
public class OCurrentStorageVersions {
26+
public final int storageVersion;
27+
28+
public OCurrentStorageVersions(OStorageConfiguration configuration) {
29+
this.storageVersion = configuration.storageVersion;
30+
}
31+
32+
public boolean classesAreDetectedByClusterId() {
33+
return storageVersion >= 10;
34+
}
35+
}

core/src/main/java/com/orientechnologies/orient/core/db/record/ODatabaseRecord.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,6 @@ public <REC extends ORecordInternal<?>> ORecordIteratorCluster<REC> browseCluste
156156
public void setDataSegmentStrategy(ODataSegmentStrategy dataSegmentStrategy);
157157

158158
public OSBTreeCollectionManager getSbTreeCollectionManager();
159+
160+
public OCurrentStorageVersions getStorageVersions();
159161
}

core/src/main/java/com/orientechnologies/orient/core/db/record/ODatabaseRecordAbstract.java

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import com.orientechnologies.orient.core.db.record.ridbag.sbtree.OSBTreeCollectionManagerShared;
5555
import com.orientechnologies.orient.core.dictionary.ODictionary;
5656
import com.orientechnologies.orient.core.exception.ODatabaseException;
57+
import com.orientechnologies.orient.core.exception.OSchemaException;
5758
import com.orientechnologies.orient.core.exception.OSecurityAccessException;
5859
import com.orientechnologies.orient.core.fetch.OFetchHelper;
5960
import com.orientechnologies.orient.core.hook.OHookThreadLocal;
@@ -79,6 +80,7 @@
7980
import com.orientechnologies.orient.core.query.OQuery;
8081
import com.orientechnologies.orient.core.record.ORecord;
8182
import com.orientechnologies.orient.core.record.ORecordInternal;
83+
import com.orientechnologies.orient.core.record.ORecordSchemaAwareAbstract;
8284
import com.orientechnologies.orient.core.record.impl.ODocument;
8385
import com.orientechnologies.orient.core.schedule.OSchedulerTrigger;
8486
import com.orientechnologies.orient.core.serialization.serializer.record.ORecordSerializer;
@@ -116,6 +118,7 @@ public abstract class ODatabaseRecordAbstract extends ODatabaseWrapperAbstract<O
116118
private boolean mvcc;
117119
private boolean validation;
118120
private ODataSegmentStrategy dataSegmentStrategy = new ODefaultDataSegmentStrategy();
121+
private OCurrentStorageVersions currentStorageVersions;
119122

120123
public ODatabaseRecordAbstract(final String iURL, final byte iRecordType) {
121124
super(new ODatabaseRaw(iURL));
@@ -140,6 +143,8 @@ public <DB extends ODatabase> DB open(final String iUserName, final String iUser
140143

141144
try {
142145
super.open(iUserName, iUserPassword);
146+
147+
currentStorageVersions = new OCurrentStorageVersions(getStorage().getConfiguration());
143148
sbTreeCollectionManager = new OSBTreeCollectionManagerProxy(this, getStorage().getResource(
144149
OSBTreeCollectionManager.class.getSimpleName(), new Callable<OSBTreeCollectionManager>() {
145150
@Override
@@ -216,6 +221,7 @@ public <DB extends ODatabase> DB create() {
216221
try {
217222
super.create();
218223

224+
currentStorageVersions = new OCurrentStorageVersions(getStorage().getConfiguration());
219225
sbTreeCollectionManager = new OSBTreeCollectionManagerProxy(this, getStorage().getResource(
220226
OSBTreeCollectionManager.class.getSimpleName(), new Callable<OSBTreeCollectionManager>() {
221227
@Override
@@ -271,6 +277,11 @@ public OSBTreeCollectionManager call() throws Exception {
271277
return (DB) this;
272278
}
273279

280+
@Override
281+
public OCurrentStorageVersions getStorageVersions() {
282+
return currentStorageVersions;
283+
}
284+
274285
@Override
275286
public void drop() {
276287
checkOpeness();
@@ -836,14 +847,30 @@ else if (stream == null || stream.length == 0)
836847
if (isNew && rid.clusterId < 0)
837848
rid.clusterId = iClusterName != null ? getClusterIdByName(iClusterName) : getDefaultClusterId();
838849

839-
if (rid.clusterId > -1 && iClusterName == null)
840-
iClusterName = getClusterNameById(rid.clusterId);
850+
if (rid.clusterId > -1) {
851+
if (iClusterName == null)
852+
iClusterName = getClusterNameById(rid.clusterId);
853+
854+
if (isNew && record instanceof ORecordSchemaAwareAbstract) {
855+
final ORecordSchemaAwareAbstract recordSchemaAware = (ORecordSchemaAwareAbstract) record;
856+
final OClass recordClass = recordSchemaAware.getSchemaClass();
857+
final OClass clusterIdClass = metadata.getSchema().getClassByClusterId(rid.clusterId);
858+
if (recordClass == null && clusterIdClass != null || clusterIdClass == null && recordClass != null
859+
|| (recordClass != null && !recordClass.equals(clusterIdClass)))
860+
throw new OSchemaException("Record saved into cluster " + iClusterName + " should be saved with class "
861+
+ clusterIdClass + " but saved with class " + recordClass);
862+
}
863+
}
864+
865+
if (wasNew)
866+
checkSecurity(ODatabaseSecurityResources.CLUSTER, ORole.PERMISSION_CREATE, iClusterName);
867+
else
868+
checkSecurity(ODatabaseSecurityResources.CLUSTER, ORole.PERMISSION_UPDATE, iClusterName);
841869

842870
if (stream != null && stream.length > 0) {
843871
if (iCallTriggers)
844872
if (wasNew) {
845873
// CHECK ACCESS ON CLUSTER
846-
checkSecurity(ODatabaseSecurityResources.CLUSTER, ORole.PERMISSION_CREATE, iClusterName);
847874
if (callbackHooks(TYPE.BEFORE_CREATE, record) == RESULT.RECORD_CHANGED) {
848875
// RECORD CHANGED IN TRIGGER, REACQUIRE IT
849876
record.unsetDirty();
@@ -855,7 +882,6 @@ else if (stream == null || stream.length == 0)
855882
}
856883
} else {
857884
// CHECK ACCESS ON CLUSTER
858-
checkSecurity(ODatabaseSecurityResources.CLUSTER, ORole.PERMISSION_UPDATE, iClusterName);
859885
if (callbackHooks(TYPE.BEFORE_UPDATE, record) == RESULT.RECORD_CHANGED) {
860886
// RECORD CHANGED IN TRIGGER, REACQUIRE IT
861887
record.unsetDirty();

core/src/main/java/com/orientechnologies/orient/core/metadata/OMetadataDefault.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ private void init(final boolean iLoad) {
109109

110110
schema = new OSchemaProxy(database.getStorage().getResource(OSchema.class.getSimpleName(), new Callable<OSchemaShared>() {
111111
public OSchemaShared call() {
112-
final OSchemaShared instance = new OSchemaShared(schemaClusterId);
112+
ODatabaseRecord database = getDatabase();
113+
final OSchemaShared instance = new OSchemaShared(database.getStorageVersions().classesAreDetectedByClusterId());
113114
if (iLoad)
114115
instance.load();
115116
return instance;

core/src/main/java/com/orientechnologies/orient/core/metadata/schema/OClassImpl.java

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ public OClass setName(final String iName) {
227227

228228
public void setNameInternal(final String iName) {
229229
getDatabase().checkSecurity(ODatabaseSecurityResources.SCHEMA, ORole.PERMISSION_UPDATE);
230-
owner.changeClassName(name, iName);
230+
owner.changeClassName(name, iName, this);
231231
name = iName;
232232
}
233233

@@ -258,15 +258,15 @@ public OClass setShortName(String iShortName) {
258258

259259
public void setShortNameInternal(final String iShortName) {
260260
getDatabase().checkSecurity(ODatabaseSecurityResources.SCHEMA, ORole.PERMISSION_UPDATE);
261+
262+
String oldName = null;
263+
261264
if (this.shortName != null)
262-
// UNREGISTER ANY PREVIOUS SHORT NAME
263-
owner.classes.remove(this.shortName.toLowerCase());
265+
oldName = this.shortName.toLowerCase();
264266

265267
this.shortName = iShortName;
266268

267-
// REGISTER IT
268-
if (null != iShortName)
269-
owner.classes.put(iShortName.toLowerCase(), this);
269+
owner.changeClassName(oldName, shortName, this);
270270
}
271271

272272
public String getStreamableName() {
@@ -557,34 +557,39 @@ private void addClusterIdToIndexes(int iId) {
557557
}
558558
}
559559

560-
public OClass addClusterIdInternal(final int iId) {
560+
public OClass addClusterIdInternal(final int clusterId) {
561+
owner.checkClusterCanBeAdded(clusterId, this);
562+
561563
for (int currId : clusterIds)
562-
if (currId == iId)
564+
if (currId == clusterId)
563565
// ALREADY ADDED
564566
return this;
565567

566568
clusterIds = OArrays.copyOf(clusterIds, clusterIds.length + 1);
567-
clusterIds[clusterIds.length - 1] = iId;
569+
clusterIds[clusterIds.length - 1] = clusterId;
568570
Arrays.sort(clusterIds);
569571

570572
polymorphicClusterIds = OArrays.copyOf(polymorphicClusterIds, polymorphicClusterIds.length + 1);
571-
polymorphicClusterIds[polymorphicClusterIds.length - 1] = iId;
573+
polymorphicClusterIds[polymorphicClusterIds.length - 1] = clusterId;
572574
Arrays.sort(polymorphicClusterIds);
573575

574576
if (defaultClusterId == -1)
575-
defaultClusterId = iId;
577+
defaultClusterId = clusterId;
576578

577579
setDirty();
578-
addClusterIdToIndexes(iId);
580+
addClusterIdToIndexes(clusterId);
579581

582+
owner.addClusterForClass(clusterId, this);
580583
return this;
581584
}
582585

583-
public OClass removeClusterId(final int iId) {
586+
public OClass removeClusterId(final int clusterId) {
584587
getDatabase().checkSecurity(ODatabaseSecurityResources.SCHEMA, ORole.PERMISSION_UPDATE);
585-
final String cmd = String.format("alter class %s removecluster %d", name, iId);
588+
final String cmd = String.format("alter class %s removecluster %d", name, clusterId);
586589
getDatabase().command(new OCommandSQL(cmd)).execute();
587-
removeClusterIdInternal(iId);
590+
removeClusterIdInternal(clusterId);
591+
592+
owner.removeClusterForClass(clusterId, this);
588593
return this;
589594
}
590595

core/src/main/java/com/orientechnologies/orient/core/metadata/schema/OSchema.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,6 @@ public interface OSchema {
9797
* Cluster name
9898
*/
9999
public Set<OClass> getClassesRelyOnCluster(String iClusterName);
100+
101+
public OClass getClassByClusterId(int clusterId);
100102
}

core/src/main/java/com/orientechnologies/orient/core/metadata/schema/OSchemaProxy.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,4 +191,9 @@ public String toString() {
191191
public Set<OClass> getClassesRelyOnCluster(final String iClusterName) {
192192
return delegate.getClassesRelyOnCluster(iClusterName);
193193
}
194+
195+
@Override
196+
public OClass getClassByClusterId(int clusterId) {
197+
return delegate.getClassByClusterId(clusterId);
198+
}
194199
}

0 commit comments

Comments
 (0)