Changeset 19635


Ignore:
Timestamp:
02/03/12 09:58:15 (4 months ago)
Author:
sys
Message:

maj Orient rev 4779 RC8

Location:
trunk
Files:
25 added
3 deleted
157 edited

Legend:

Unmodified
Added
Removed
  • trunk/Res_Orient/commons/java/com/orientechnologies/common/collection/OMVRBTree.java

    r19448 r19635  
    23902390         * @param p 
    23912391         *          Node to remove 
    2392          */ 
    2393         protected void removeNode(OMVRBTreeEntry<K, V> p) { 
     2392   * 
     2393   * @return Node that was removed. Passed and removed nodes may be different in case node to remove contains two children. 
     2394   *         In this case node successor will be found and removed but it's content will be copied to the node that was passed in method. 
     2395         */ 
     2396        protected OMVRBTreeEntry<K, V> removeNode(OMVRBTreeEntry<K, V> p) { 
    23942397                modCount++; 
    23952398                // If strictly internal, copy successor's element to p and then make p 
     
    24362439                        } 
    24372440                } 
     2441     
     2442    return p; 
    24382443        } 
    24392444 
  • trunk/Res_Orient/commons/java/com/orientechnologies/common/concur/resource/OSharedContainerImpl.java

    r17961 r19635  
    2323 
    2424/** 
    25  * Shared container that works with callbacks like closures. 
     25 * Shared container that works with callbacks like closures. If the resource implements the {@link OSharedResource} interface then 
     26 * the resource is locked until is removed. 
    2627 *  
    2728 * @author Luca Garulli (l.garulli--at--orientechnologies.com) 
     
    3738 
    3839        public synchronized <T> T removeResource(final String iName) { 
    39                 return (T) sharedResources.remove(iName); 
     40                T resource = (T) sharedResources.remove(iName); 
     41 
     42                if (resource instanceof OSharedResource) 
     43                        ((OSharedResource) resource).releaseExclusiveLock(); 
     44 
     45                return resource; 
    4046        } 
    4147 
     
    4955                                throw new OException("Error on creation of shared resource", e); 
    5056                        } 
     57 
     58                        if (value instanceof OSharedResource) 
     59                                ((OSharedResource) value).acquireExclusiveLock(); 
     60 
    5161                        sharedResources.put(iName, value); 
    5262                } 
  • trunk/Res_Orient/commons/java/com/orientechnologies/common/profiler/OProfiler.java

    r17961 r19635  
    2424import java.util.Map; 
    2525import java.util.Map.Entry; 
     26import java.util.Timer; 
     27import java.util.TimerTask; 
    2628 
    2729/** 
     
    4143        private Map<String, OProfilerHookValue> hooks; 
    4244        private Date                                                                                                            lastReset; 
     45 
     46        private volatile Timer                                                                  timer; 
     47        private volatile boolean                                                                autoDumpReset; 
    4348 
    4449        protected static final OProfiler                                instance        = new OProfiler(); 
     
    396401        } 
    397402 
    398         private synchronized long updateEntry(Map<String, OProfilerEntry> iValues, final String iName, final long iValue) { 
     403        private synchronized long updateEntry(final Map<String, OProfilerEntry> iValues, final String iName, final long iValue) { 
    399404                if (recording < 0) 
    400405                        return iValue; 
     
    453458                } 
    454459        } 
     460 
     461        public void setAutoDump(final int iSeconds) { 
     462                if (timer != null) { 
     463                        timer.cancel(); 
     464                        timer = null; 
     465                } 
     466 
     467                if (iSeconds > 0) { 
     468                        final int ms = iSeconds * 1000; 
     469 
     470                        timer = new Timer(true); 
     471                        timer.scheduleAtFixedRate(new TimerTask() { 
     472 
     473                                @Override 
     474                                public void run() { 
     475                                        System.out.println(OProfiler.getInstance().dump()); 
     476                                        if (autoDumpReset) 
     477                                                reset(); 
     478                                } 
     479                        }, ms, ms); 
     480                } 
     481        } 
     482 
     483        public void setAutoDumpReset(final boolean iNewValue) { 
     484                autoDumpReset = iNewValue; 
     485        } 
    455486} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/OConstants.java

    r19245 r19635  
    1717 
    1818public class OConstants { 
    19         public static final String      ORIENT_VERSION  = "1.0rc8-SNAPSHOT"; 
     19        public static final String      ORIENT_VERSION  = "1.0rc8"; 
    2020        public static final String      ORIENT_URL                      = "www.orientechnologies.com"; 
    2121 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/Orient.java

    r19431 r19635  
    3333import com.orientechnologies.common.profiler.OProfiler; 
    3434import com.orientechnologies.orient.core.config.OGlobalConfiguration; 
     35import com.orientechnologies.orient.core.db.ODatabaseFactory; 
    3536import com.orientechnologies.orient.core.db.ODatabaseLifecycleListener; 
     37import com.orientechnologies.orient.core.db.document.ODatabaseDocumentPool; 
     38import com.orientechnologies.orient.core.db.graph.OGraphDatabasePool; 
     39import com.orientechnologies.orient.core.db.object.ODatabaseObjectPool; 
    3640import com.orientechnologies.orient.core.engine.OEngine; 
    3741import com.orientechnologies.orient.core.engine.local.OEngineLocal; 
     
    5155        protected final List<OOrientListener>                   listeners                                                       = new ArrayList<OOrientListener>(); 
    5256        protected ORecordFactoryManager                                         recordFactoryManager    = new ORecordFactoryManager(); 
     57        protected ODatabaseFactory                                                              databaseFactory                         = new ODatabaseFactory(); 
    5358        protected volatile boolean                                                              active                                                          = false; 
    5459 
     
    251256                                return; 
    252257 
     258                        shutdownHook.cancel(); 
     259 
    253260                        OLogManager.instance().debug(this, "Orient Engine is shutting down..."); 
     261 
     262                        // CLOSE ALL THE GLOBAL DATABASE POOLS 
     263                        ODatabaseDocumentPool.global().close(); 
     264                        ODatabaseObjectPool.global().close(); 
     265                        OGraphDatabasePool.global().close(); 
     266 
     267                        // CLOSE ALL DATABASES 
     268                        databaseFactory.shutdown(); 
    254269 
    255270                        // CLOSE ALL THE STORAGES 
     
    310325        } 
    311326 
     327        public ODatabaseFactory getDatabaseFactory() { 
     328                return databaseFactory; 
     329        } 
     330 
    312331        public void registerListener(final OOrientListener iListener) { 
    313332                if (!listeners.contains(iListener)) 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/OrientShutdownHook.java

    r17050 r19635  
    2828                Orient.instance().shutdown(); 
    2929        } 
     30 
     31        public void cancel() { 
     32                try { 
     33                        Runtime.getRuntime().removeShutdownHook(this); 
     34                } catch (IllegalStateException e) { 
     35                } 
     36        } 
    3037} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/cache/OAbstractRecordCache.java

    r19431 r19635  
    1616package com.orientechnologies.orient.core.cache; 
    1717 
     18import com.orientechnologies.common.concur.resource.OSharedResourceAbstract; 
     19import com.orientechnologies.common.profiler.OProfiler; 
     20import com.orientechnologies.common.profiler.OProfiler.OProfilerHookValue; 
     21import com.orientechnologies.orient.core.id.ORID; 
     22import com.orientechnologies.orient.core.record.ORecordInternal; 
     23 
    1824import java.util.Collection; 
    1925import java.util.HashSet; 
    2026import java.util.Set; 
    2127 
    22 import com.orientechnologies.common.concur.resource.OSharedResourceAbstract; 
    23 import com.orientechnologies.common.log.OLogManager; 
    24 import com.orientechnologies.common.profiler.OProfiler; 
    25 import com.orientechnologies.common.profiler.OProfiler.OProfilerHookValue; 
    26 import com.orientechnologies.orient.core.Orient; 
    27 import com.orientechnologies.orient.core.id.ORID; 
    28 import com.orientechnologies.orient.core.memory.OMemoryWatchDog.Listener; 
    29 import com.orientechnologies.orient.core.record.ORecordInternal; 
    30  
    3128/** 
    32  * Cache of documents. 
    33  *  
     29 * Cache of documents. Delegates real work on storing to {@link OCache} implementation passed at creation time 
     30 * leaving only DB specific functionality 
     31 * 
    3432 * @author Luca Garulli 
    35  *  
    3633 */ 
    3734public abstract class OAbstractRecordCache extends OSharedResourceAbstract { 
    38         protected boolean                               enabled                                 = true; 
    39         protected int                                           maxSize; 
    40         protected ORecordCache  entries; 
     35  protected OCache underlying; 
     36  protected String profilerPrefix = "noname"; 
     37  protected int excludedCluster = -1; 
    4138 
    42         protected Listener                      watchDogListener; 
    43         protected String                                profilerPrefix; 
    44         protected int                                           excludedCluster = -1; 
     39  /** 
     40   * Create cache backed by given implementation 
     41   * 
     42   * @param impl actual implementation of cache 
     43   */ 
     44  public OAbstractRecordCache(final OCache impl) { 
     45    underlying = impl; 
     46  } 
    4547 
    46         /** 
    47          * Create the cache of iMaxSize size. 
    48          *  
    49          * @param iMaxSize 
    50          *          Maximum number of elements for the cache 
    51          */ 
    52         public OAbstractRecordCache(final String iProfilerPrefix, final int iMaxSize) { 
    53                 profilerPrefix = iProfilerPrefix; 
    54                 maxSize = iMaxSize; 
     48  /** 
     49   * Tell whether cache is enabled 
     50   * 
     51   * @return {@code true} if cache enabled at call time, otherwise - {@code false} 
     52   */ 
     53  public boolean isEnabled() { 
     54    return underlying.isEnabled(); 
     55  } 
    5556 
    56                 final int initialSize = maxSize > -1 ? maxSize + 1 : 1000; 
    57                 entries = new ORecordCache(maxSize, initialSize, 0.75f); 
    58         } 
     57  /** 
     58   * Switch cache state between enabled and disabled 
     59   * 
     60   * @param enable pass {@code true} to enable, otherwise - {@code false} 
     61   */ 
     62  public void setEnable(final boolean enable) { 
     63    if (enable) underlying.enable(); 
     64    else underlying.disable(); 
     65  } 
    5966 
    60         public boolean isEnabled() { 
    61                 return enabled; 
    62         } 
     67  /** 
     68   * Remove record with specified identifier 
     69   * 
     70   * @param rid unique identifier of record 
     71   * @return record stored in cache if any, otherwise - {@code null} 
     72   */ 
     73  public ORecordInternal<?> freeRecord(final ORID rid) { 
     74    return underlying.remove(rid); 
     75  } 
    6376 
    64         public void setEnable(final boolean iValue) { 
    65                 enabled = iValue; 
    66                 if (!iValue) 
    67                         entries.clear(); 
    68         } 
     77  /** 
     78   * Remove all records belonging to specified cluster 
     79   * 
     80   * @param cid identifier of cluster 
     81   */ 
     82  public void freeCluster(final int cid) { 
     83    final Set<ORID> toRemove = new HashSet<ORID>(underlying.size() / 2); 
    6984 
    70         public ORecordInternal<?> freeRecord(final ORID iRID) { 
    71                 if (!enabled) 
    72                         // PRECONDITIONS 
    73                         return null; 
     85    final Set<ORID> keys = new HashSet<ORID>(underlying.keys()); 
     86    for (final ORID id : keys ) 
     87      if (id.getClusterId() == cid) toRemove.add(id); 
    7488 
    75                 acquireExclusiveLock(); 
    76                 try { 
    77                         return entries.remove(iRID); 
    78                 } finally { 
    79                         releaseExclusiveLock(); 
    80                 } 
    81         } 
     89    for (final ORID ridToRemove : toRemove) 
     90      underlying.remove(ridToRemove); 
     91  } 
    8292 
    83         public void freeCluster(final int clusterId) { 
    84                 if (!enabled) 
    85                         // PRECONDITIONS 
    86                         return; 
     93  /** 
     94   * Remove record entry 
     95   * 
     96   * @param rid unique record identifier 
     97   */ 
     98  public void deleteRecord(final ORID rid) { 
     99    underlying.remove(rid); 
     100  } 
    87101 
    88                 acquireExclusiveLock(); 
    89                 final Set<ORID> toRemove = new HashSet<ORID>(); 
    90                 try { 
    91                         for (ORID entry : entries.keySet()) { 
    92                                 if (entry.getClusterId() == clusterId) { 
    93                                         toRemove.add(entry); 
    94                                 } 
    95                         } 
    96                         for (ORID ridToRemove : toRemove) { 
    97                                 entries.remove(ridToRemove); 
    98                         } 
    99                 } finally { 
    100                         toRemove.clear(); 
    101                         releaseExclusiveLock(); 
    102                 } 
    103         } 
     102  /** 
     103   * Clear the entire cache by removing all the entries 
     104   */ 
     105  public void clear() { 
     106    underlying.clear(); 
     107  } 
    104108 
    105         /** 
    106          * Remove multiple records from the cache in one shot. 
    107          *  
    108          * @param iRecords 
    109          *          List of RIDs as RecordID instances 
    110          */ 
    111         public void removeRecords(final Collection<ORID> iRecords) { 
    112                 if (!enabled) 
    113                         // PRECONDITIONS 
    114                         return; 
     109  /** 
     110   * Total number of cached entries 
     111   * 
     112   * @return non-negative integer 
     113   */ 
     114  public int getSize() { 
     115    return underlying.size(); 
     116  } 
    115117 
    116                 acquireExclusiveLock(); 
    117                 try { 
    118                         for (ORID id : iRecords) 
    119                                 entries.remove(id); 
    120                 } finally { 
    121                         releaseExclusiveLock(); 
    122                 } 
    123         } 
     118  /** 
     119   * Maximum number of items cache should keep 
     120   * 
     121   * @return non-negative integer 
     122   */ 
     123  public int getMaxSize() { 
     124    return underlying.limit(); 
     125  } 
    124126 
    125         /** 
    126          * Delete a record entry from both database and storage caches. 
    127          *  
    128          * @param iRecord 
    129          *          Record to remove 
    130          */ 
    131         public void deleteRecord(final ORID iRecord) { 
    132                 if (!enabled) 
    133                         // PRECONDITIONS 
    134                         return; 
     127  /** 
     128   * All operations running at cache initialization stage 
     129   */ 
     130  public void startup() { 
     131    underlying.startup(); 
    135132 
    136                 acquireExclusiveLock(); 
    137                 try { 
    138                         entries.remove(iRecord); 
    139                 } finally { 
    140                         releaseExclusiveLock(); 
    141                 } 
    142         } 
     133    OProfiler.getInstance().registerHookValue(profilerPrefix + ".cache.enabled", new OProfilerHookValue() { 
     134      public Object getValue() { 
     135        return isEnabled(); 
     136      } 
     137    }); 
    143138 
    144         public boolean existsRecord(final ORID iRID) { 
    145                 if (!enabled) 
    146                         // PRECONDITIONS 
    147                         return false; 
     139    OProfiler.getInstance().registerHookValue(profilerPrefix + ".cache.current", new OProfilerHookValue() { 
     140      public Object getValue() { 
     141        return getSize(); 
     142      } 
     143    }); 
    148144 
    149                 acquireSharedLock(); 
    150                 try { 
    151                         return entries.containsKey(iRID); 
    152                 } finally { 
    153                         releaseSharedLock(); 
    154                 } 
    155         } 
     145    OProfiler.getInstance().registerHookValue(profilerPrefix + ".cache.max", new OProfilerHookValue() { 
     146      public Object getValue() { 
     147        return getMaxSize(); 
     148      } 
     149    }); 
     150  } 
    156151 
    157         /** 
    158          * Clear the entire cache by removing all the entries. 
    159          */ 
    160         public void clear() { 
    161                 if (!enabled) 
    162                         // PRECONDITIONS 
    163                         return; 
    164  
    165                 acquireExclusiveLock(); 
    166                 try { 
    167                         entries.clear(); 
    168  
    169                 } finally { 
    170                         releaseExclusiveLock(); 
    171                 } 
    172         } 
    173  
    174         /** 
    175          * Return the total cached entries. 
    176          *  
    177          * @return 
    178          */ 
    179         public int getSize() { 
    180                 acquireSharedLock(); 
    181                 try { 
    182                         return entries.size(); 
    183  
    184                 } finally { 
    185                         releaseSharedLock(); 
    186                 } 
    187         } 
    188  
    189         public int getMaxSize() { 
    190                 acquireSharedLock(); 
    191                 try { 
    192                         return maxSize; 
    193  
    194                 } finally { 
    195                         releaseSharedLock(); 
    196                 } 
    197         } 
    198  
    199         public void shutdown() { 
    200                 acquireExclusiveLock(); 
    201  
    202                 try { 
    203                         entries.clear(); 
    204                         Orient.instance().getMemoryWatchDog().removeListener(watchDogListener); 
    205                         watchDogListener = null; 
    206  
    207                 } finally { 
    208                         releaseExclusiveLock(); 
    209                 } 
    210         } 
    211  
    212         public void setMaxSize(final int iMaxSize) { 
    213                 maxSize = iMaxSize; 
    214         } 
    215  
    216         public void startup() { 
    217                 watchDogListener = Orient.instance().getMemoryWatchDog().addListener(new Listener() { 
    218                         public void memoryUsageLow(final long iFreeMemory, final long iFreeMemoryPercentage) { 
    219                                 acquireExclusiveLock(); 
    220                                 try { 
    221                                         if (iFreeMemoryPercentage < 10) { 
    222                                                 OLogManager.instance().debug(this, "Free memory is low (%d%%): clearing %d resources", iFreeMemoryPercentage, 
    223                                                                 entries.size()); 
    224                                                 entries.clear(); 
    225                                         } else { 
    226                                                 final int oldSize = entries.size(); 
    227                                                 if (oldSize == 0) 
    228                                                         // UNACTIVE 
    229                                                         return; 
    230  
    231                                                 final int threshold = (int) (oldSize * 0.9f); 
    232  
    233                                                 entries.removeEldestItems(threshold); 
    234                                                 OLogManager.instance().debug(this, "Low memory (%d%%): auto reduce the record cache size from %d to %d", 
    235                                                                 iFreeMemoryPercentage, oldSize, threshold); 
    236                                         } 
    237                                 } catch (Exception e) { 
    238                                         OLogManager.instance().error(this, "Error while freeing resources", e); 
    239                                 } finally { 
    240                                         releaseExclusiveLock(); 
    241                                 } 
    242                         } 
    243                 }); 
    244  
    245                 OProfiler.getInstance().registerHookValue(profilerPrefix + ".cache.enabled", new OProfilerHookValue() { 
    246                         public Object getValue() { 
    247                                 return enabled; 
    248                         } 
    249                 }); 
    250  
    251                 OProfiler.getInstance().registerHookValue(profilerPrefix + ".cache.current", new OProfilerHookValue() { 
    252                         public Object getValue() { 
    253                                 acquireSharedLock(); 
    254                                 try { 
    255                                         return entries.size(); 
    256                                 } finally { 
    257                                         releaseSharedLock(); 
    258                                 } 
    259                         } 
    260                 }); 
    261  
    262                 OProfiler.getInstance().registerHookValue(profilerPrefix + ".cache.max", new OProfilerHookValue() { 
    263                         public Object getValue() { 
    264                                 return maxSize; 
    265                         } 
    266                 }); 
    267         } 
    268  
    269         public int getExcludedCluster() { 
    270                 return excludedCluster; 
    271         } 
    272  
    273         public void setExcludedCluster(int excludedCluster) { 
    274                 this.excludedCluster = excludedCluster; 
    275         } 
     152  /** 
     153   * All operations running at cache destruction stage 
     154   */ 
     155  public void shutdown() { 
     156    underlying.shutdown(); 
     157  } 
    276158} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/cache/OLevel1RecordCache.java

    r19431 r19635  
    1616package com.orientechnologies.orient.core.cache; 
    1717 
     18import static com.orientechnologies.orient.core.storage.OStorage.CLUSTER_INDEX_NAME; 
     19 
    1820import com.orientechnologies.common.profiler.OProfiler; 
    1921import com.orientechnologies.orient.core.config.OGlobalConfiguration; 
     22import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal; 
    2023import com.orientechnologies.orient.core.db.record.ODatabaseRecord; 
    2124import com.orientechnologies.orient.core.id.ORID; 
    2225import com.orientechnologies.orient.core.record.ORecordInternal; 
    23 import com.orientechnologies.orient.core.storage.OStorage; 
    2426 
    2527/** 
    26  * Per database cache of documents. It's not synchronized since database object are not thread-safes. 
     28 * Level1 cache. it's one to one with record database instances. 
    2729 *  
    2830 * @author Luca Garulli 
    29  *  
    3031 */ 
    3132public class OLevel1RecordCache extends OAbstractRecordCache { 
     33        private OLevel2RecordCache      secondary       = null; 
     34        private String                                                  CACHE_HIT; 
     35        private String                                                  CACHE_MISS; 
    3236 
    33         private final ODatabaseRecord   database; 
    34         private OLevel2RecordCache              level2cache; 
    35         private String                                                          PROFILER_CACHE_FOUND; 
    36         private String                                                          PROFILER_CACHE_NOTFOUND; 
    37  
    38         public OLevel1RecordCache(final ODatabaseRecord iDatabase) { 
    39                 super("db." + iDatabase.getName(), OGlobalConfiguration.CACHE_LEVEL1_SIZE.getValueAsInteger()); 
    40                 database = iDatabase; 
     37        public OLevel1RecordCache() { 
     38                super(new OCacheLocator().primaryCache()); 
    4139        } 
    4240 
    4341        @Override 
    4442        public void startup() { 
    45                 profilerPrefix = "db." + database.getName(); 
    46                 PROFILER_CACHE_FOUND = profilerPrefix + ".cache.found"; 
    47                 PROFILER_CACHE_NOTFOUND = profilerPrefix + ".cache.notFound"; 
     43                ODatabaseRecord db = ODatabaseRecordThreadLocal.INSTANCE.get(); 
     44                secondary = db.getLevel2Cache(); 
     45 
     46                profilerPrefix = "db." + db.getName(); 
     47                CACHE_HIT = profilerPrefix + ".cache.found"; 
     48                CACHE_MISS = profilerPrefix + ".cache.notFound"; 
     49 
     50                excludedCluster = db.getClusterIdByName(CLUSTER_INDEX_NAME); 
    4851 
    4952                super.startup(); 
    50                 setExcludedCluster(database.getClusterIdByName(OStorage.CLUSTER_INDEX_NAME)); 
    51  
    52                 level2cache = (OLevel2RecordCache) database.getLevel2Cache(); 
    53                 enabled = OGlobalConfiguration.CACHE_LEVEL1_ENABLED.getValueAsBoolean(); 
    54         } 
    55  
    56         public void updateRecord(final ORecordInternal<?> iRecord) { 
    57                 if (enabled) { 
    58                         if (iRecord.getIdentity().getClusterId() == excludedCluster) 
    59                                 // EXCLUDED CLUSTER 
    60                                 return; 
    61  
    62                         if (!iRecord.getIdentity().isValid()) 
    63                                 // INVALID RECORD 
    64                                 return; 
    65  
    66                         acquireExclusiveLock(); 
    67                         try { 
    68                                 if (entries.get(iRecord.getIdentity()) != iRecord) 
    69                                         entries.put(iRecord.getIdentity(), iRecord); 
    70                         } finally { 
    71                                 releaseExclusiveLock(); 
    72                         } 
    73                 } 
    74  
    75                 level2cache.updateRecord(iRecord); 
     53                setEnable(OGlobalConfiguration.CACHE_LEVEL1_ENABLED.getValueAsBoolean()); 
    7654        } 
    7755 
    7856        /** 
    79          * Search a record in the cache and if found add it in the Database's level-1 cache. 
     57         * Pushes record to cache. Identifier of record used as access key 
    8058         *  
    81          * @param iRID 
    82          *          RecordID to search 
    83          * @param iDbCache 
    84          *          Database's cache 
    85          * @return The record if found, otherwise null 
     59         * @param record 
     60         *          record that should be cached 
    8661         */ 
    87         public ORecordInternal<?> findRecord(final ORID iRID) { 
    88                 if (!enabled) 
    89                         // PRECONDITIONS 
     62        public void updateRecord(final ORecordInternal<?> record) { 
     63                if (!isEnabled() || record.getIdentity().getClusterId() == excludedCluster || !record.getIdentity().isValid()) 
     64                        return; 
     65 
     66                underlying.lock(record.getIdentity()); 
     67                try { 
     68                        if (underlying.get(record.getIdentity()) != record) 
     69                                underlying.put(record); 
     70                } finally { 
     71                        underlying.unlock(record.getIdentity()); 
     72                } 
     73 
     74                secondary.updateRecord(record); 
     75        } 
     76 
     77        /** 
     78         * Looks up for record in cache by it's identifier. Optionally look up in secondary cache and update primary with found record 
     79         *  
     80         * @param rid 
     81         *          unique identifier of record 
     82         * @return record stored in cache if any, otherwise - {@code null} 
     83         */ 
     84        public ORecordInternal<?> findRecord(final ORID rid) { 
     85                if (!isEnabled()) 
    9086                        return null; 
    9187 
    9288                ORecordInternal<?> record; 
     89                underlying.lock(rid); 
     90                try { 
     91                        record = underlying.get(rid); 
    9392 
    94                 // SEARCH INTO DATABASE'S 1-LEVEL CACHE 
    95                 acquireSharedLock(); 
    96                 try { 
    97                         record = entries.get(iRID); 
     93                        if (record == null) { 
     94                                record = secondary.retrieveRecord(rid); 
     95 
     96                                if (record != null) 
     97                                        underlying.put(record); 
     98                        } 
    9899                } finally { 
    99                         releaseSharedLock(); 
     100                        underlying.unlock(rid); 
    100101                } 
    101102 
    102                 if (record == null) { 
    103                         // SEARCH INTO THE STORAGE'S 2-LEVEL CACHE 
    104                         record = level2cache.retrieveRecord(iRID); 
    105  
    106                         if (record != null) { 
    107                                 // FOUND: MOVE IT INTO THE DB'S CACHE 
    108                                 acquireExclusiveLock(); 
    109                                 try { 
    110                                         entries.put(record.getIdentity(), record); 
    111                                 } finally { 
    112                                         releaseExclusiveLock(); 
    113                                 } 
    114                         } 
    115                 } 
    116  
    117                 OProfiler.getInstance().updateCounter(record != null ? PROFILER_CACHE_FOUND : PROFILER_CACHE_NOTFOUND, +1); 
     103                OProfiler.getInstance().updateCounter(record != null ? CACHE_HIT : CACHE_MISS, 1L); 
    118104 
    119105                return record; 
     
    121107 
    122108        /** 
    123          * Delete a record entry from both database and storage caches. 
     109         * Removes record with specified identifier from both primary and secondary caches 
    124110         *  
    125          * @param iRecord 
    126          *          Record to remove 
     111         * @param rid 
     112         *          unique identifier of record 
    127113         */ 
    128         public void deleteRecord(final ORID iRecord) { 
    129                 super.deleteRecord(iRecord); 
    130                 level2cache.freeRecord(iRecord); 
     114        public void deleteRecord(final ORID rid) { 
     115                super.deleteRecord(rid); 
     116                secondary.freeRecord(rid); 
    131117        } 
    132118 
    133119        public void shutdown() { 
    134                 clear(); 
    135120                super.shutdown(); 
    136                 level2cache = null; 
     121                secondary = null; 
    137122        } 
    138123 
    139124        @Override 
    140125        public void clear() { 
    141                 acquireExclusiveLock(); 
    142                 try { 
    143                         if (level2cache != null) 
    144                                 // MOVE ALL THE LEVEL-1 CACHE INTO THE LEVEL-2 CACHE 
    145                                 level2cache.moveRecords(entries.values()); 
    146  
    147                         entries.clear(); 
    148                 } finally { 
    149                         releaseExclusiveLock(); 
    150                 } 
     126                moveRecordsToSecondaryCache(); 
     127                super.clear(); 
    151128        } 
    152129 
     130        private void moveRecordsToSecondaryCache() { 
     131                if (secondary == null) 
     132                        return; 
     133 
     134                for (ORID rid : underlying.keys()) 
     135                        secondary.updateRecord(underlying.get(rid)); 
     136        } 
     137 
     138        /** 
     139         * Invalidates the cache emptying all the records. 
     140         */ 
    153141        public void invalidate() { 
    154                 acquireExclusiveLock(); 
    155                 try { 
    156                         entries.clear(); 
    157                 } finally { 
    158                         releaseExclusiveLock(); 
    159                 } 
     142                underlying.clear(); 
    160143        } 
    161144 
    162145        @Override 
    163146        public String toString() { 
    164                 return "DB level1 cache records=" + getSize() + ", maxSize=" + maxSize; 
     147                return "DB level1 cache records = " + getSize() + ", maxSize= " + getMaxSize(); 
    165148        } 
    166149} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/cache/OLevel2RecordCache.java

    r19431 r19635  
    1616package com.orientechnologies.orient.core.cache; 
    1717 
    18 import java.util.Collection; 
     18import static com.orientechnologies.orient.core.config.OGlobalConfiguration.CACHE_LEVEL2_STRATEGY; 
    1919 
    20 import com.orientechnologies.orient.core.config.OGlobalConfiguration; 
    2120import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal; 
    2221import com.orientechnologies.orient.core.id.ORID; 
     
    2524 
    2625/** 
    27  * Per database cache of documents. 
     26 * Second level cache. It's shared among database instances with the same URL. 
    2827 *  
    2928 * @author Luca Garulli 
    30  *  
     29 * @author Sylvain Spinelli 
    3130 */ 
    3231public class OLevel2RecordCache extends OAbstractRecordCache { 
     
    3938 
    4039        public OLevel2RecordCache(final OStorage iStorage) { 
    41                 super("storage." + iStorage.getName(), OGlobalConfiguration.CACHE_LEVEL2_SIZE.getValueAsInteger()); 
    42                 setStrategy(OGlobalConfiguration.CACHE_LEVEL2_STRATEGY.getValueAsInteger()); 
     40                super(new OCacheLocator().secondaryCache()); 
     41                profilerPrefix = "storage." + iStorage.getName(); 
     42                strategy = STRATEGY.values()[(CACHE_LEVEL2_STRATEGY.getValueAsInteger())]; 
    4343        } 
    4444 
    4545        /** 
    46          * Moves records to the Level2 cache. Update only the records already present to avoid to put a non-updated record. 
     46         * Push record to cache. Identifier of record used as access key 
    4747         *  
    48          * @param iValues 
    49          *          Collection of records to update 
     48         * @param fresh 
     49         *          new record that should be cached 
    5050         */ 
    51         public void moveRecords(final Collection<ORecordInternal<?>> iValues) { 
    52                 if (!enabled) 
     51        public void updateRecord(final ORecordInternal<?> fresh) { 
     52                if (!isEnabled() || fresh == null || fresh.isDirty() || fresh.getIdentity().isNew() || !fresh.getIdentity().isValid() 
     53                                || fresh.getIdentity().getClusterId() == excludedCluster) 
    5354                        return; 
    5455 
    55                 acquireExclusiveLock(); 
    56                 try { 
    57  
    58                         for (ORecordInternal<?> record : iValues) { 
    59                                 if (record == null || record.isDirty() || record.getIdentity().isNew()) 
    60                                         continue; 
    61  
    62                                 if (record.getIdentity().getClusterId() == excludedCluster) 
    63                                         continue; 
    64  
    65                                 if (!record.getIdentity().isValid()) 
    66                                         // INVALID RECORD 
    67                                         continue; 
    68  
    69                                 if (record.isPinned()) { 
    70                                         final ORecordInternal<?> prevEntry = entries.get(record.getIdentity()); 
    71                                         if (prevEntry != null && prevEntry.getVersion() >= record.getVersion()) 
    72                                                 // UPDATE ONLY RECORDS NOT PRESENT OR WITH VERSION HIGHER THAN CURRENT 
    73                                                 continue; 
    74  
    75                                         record.detach(); 
    76                                         entries.put(record.getIdentity(), record); 
    77  
    78                                 } else 
    79                                         entries.remove(record.getIdentity()); 
    80                         } 
    81  
    82                 } finally { 
    83                         releaseExclusiveLock(); 
    84                 } 
    85         } 
    86  
    87         public void updateRecord(final ORecordInternal<?> iRecord) { 
    88                 if (!enabled || iRecord == null || iRecord.isDirty() || iRecord.getIdentity().isNew()) 
    89                         // PRECONDITIONS 
    90                         return; 
    91  
    92                 if (iRecord.getIdentity().getClusterId() == excludedCluster) 
    93                         return; 
    94  
    95                 if (!iRecord.getIdentity().isValid()) 
    96                         // INVALID RECORD 
    97                         return; 
    98  
    99                 acquireExclusiveLock(); 
    100                 try { 
    101                         if (iRecord.isPinned()) { 
    102                                 final ORecordInternal<?> prevEntry = entries.get(iRecord.getIdentity()); 
    103                                 if (prevEntry != null && prevEntry.getVersion() >= iRecord.getVersion()) 
    104                                         // TRY TO UPDATE AN OLD RECORD, DISCARD IT 
     56                if (fresh.isPinned()) { 
     57                        underlying.lock(fresh.getIdentity()); 
     58                        try { 
     59                                final ORecordInternal<?> current = underlying.get(fresh.getIdentity()); 
     60                                if (current != null && current.getVersion() >= fresh.getVersion()) 
    10561                                        return; 
    10662 
    107                                 if ((!ODatabaseRecordThreadLocal.INSTANCE.isDefined() || iRecord.getDatabase().isClosed())) { 
    108                                         // DB CLOSED: MAKE THE RECORD INSTANCE AS REUSABLE AFTER A DETACH 
    109                                         iRecord.detach(); 
    110                                         entries.put(iRecord.getIdentity(), iRecord); 
    111                                 } else 
    112                                         // DB OPEN: SAVES A COPY TO AVOID CHANGES IF THE SAME RECORD INSTANCE IS USED AGAIN 
    113                                         entries.put(iRecord.getIdentity(), (ORecordInternal<?>) iRecord.flatCopy()); 
    114                         } else 
    115                                 entries.remove(iRecord.getIdentity()); 
    116  
    117                 } finally { 
    118                         releaseExclusiveLock(); 
    119                 } 
     63                                if (ODatabaseRecordThreadLocal.INSTANCE.isDefined() && !ODatabaseRecordThreadLocal.INSTANCE.get().isClosed()) 
     64                                        // CACHE A COPY 
     65                                        underlying.put((ORecordInternal<?>) fresh.flatCopy()); 
     66                                else { 
     67                                        // CACHE THE DETACHED RECORD 
     68                                        fresh.detach(); 
     69                                        underlying.put(fresh); 
     70                                } 
     71                        } finally { 
     72                                underlying.unlock(fresh.getIdentity()); 
     73                        } 
     74                } else 
     75                        underlying.remove(fresh.getIdentity()); 
    12076        } 
    12177 
    12278        /** 
    123          * Retrieve the record if any following the supported strategies: 0 = If found remove it (pop): the client (database instances) 
    124          * will push it back when finished or on close. 1 = Return the instance but keep a copy in 2-level cache; this could help 
    125          * highly-concurrent environment. 
     79         * Retrieve the record if any following the supported strategies:<br> 
     80         * 0 = If found remove it (pop): the client (database instances) will push it back when finished or on close.<br> 
     81         * 1 = Return the instance but keep a copy in 2-level cache; this could help highly-concurrent environment. 
    12682         *  
    127          * @author Luca Garulli 
    128          * @author Sylvain Spinelli 
    12983         * @param iRID 
    130          * @return 
     84         *          record identity 
     85         * @return record if exists in cache, {@code null} otherwise 
    13186         */ 
    13287        protected ORecordInternal<?> retrieveRecord(final ORID iRID) { 
    133                 if (!enabled) 
    134                         // PRECONDITIONS 
     88                if (!isEnabled() || iRID.getClusterId() == excludedCluster) 
    13589                        return null; 
    13690 
    137                 if (iRID.getClusterId() == excludedCluster) 
    138                         return null; 
     91                final ORecordInternal<?> record; 
     92                underlying.lock(iRID); 
     93                try { 
     94                        record = underlying.remove(iRID); 
    13995 
    140                 acquireExclusiveLock(); 
    141                 try { 
    142                         final ORecordInternal<?> record = entries.remove(iRID); 
    14396                        if (record == null || record.isDirty()) 
    144                                 // NULL OR DIRTY RECORD: IGNORE IT 
    14597                                return null; 
    14698 
    14799                        if (strategy == STRATEGY.COPY_RECORD) 
    148100                                // PUT BACK A CLONE (THIS UPDATE ALSO THE LRU) 
    149                                 entries.put(iRID, (ORecordInternal<?>) record.flatCopy()); 
     101                                underlying.put((ORecordInternal<?>) record.flatCopy()); 
     102                } finally { 
     103                        underlying.unlock(iRID); 
     104                } 
    150105 
    151                         return record; 
    152  
    153                 } finally { 
    154                         releaseExclusiveLock(); 
    155                 } 
     106                return record; 
    156107        } 
    157108 
    158         public STRATEGY getStrategy() { 
    159                 return strategy; 
    160         } 
    161  
    162         public void setStrategy(final STRATEGY iStrategy) { 
    163                 strategy = iStrategy; 
    164         } 
    165  
    166         public void setStrategy(final int iStrategy) { 
    167                 strategy = STRATEGY.values()[iStrategy]; 
     109        public void setStrategy(final STRATEGY newStrategy) { 
     110                strategy = newStrategy; 
    168111        } 
    169112 
    170113        @Override 
    171114        public String toString() { 
    172                 return "STORAGE level2 cache records=" + getSize() + ", maxSize=" + maxSize; 
     115                return "STORAGE level2 cache records = " + getSize() + ", maxSize = " + getMaxSize(); 
    173116        } 
    174117} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/command/OCommandExecutor.java

    r19015 r19635  
    5454 
    5555        /** 
    56          * Execute the requested command after parsing it. 
    57          *  
    58          * @param iRequest 
    59          *          Command request implementation. 
    60          * @param iArgs 
    61          *          Optional variable arguments to pass to the command. 
    62          *  
    63          * @see #execute(Object...) 
    64          * @return 
    65          */ 
    66         public Object execute(OCommandRequestText iRequest, final Map<Object, Object> iArgs); 
    67  
    68         /** 
    6956         * Set the listener invoked while the command is executing. 
    7057         *  
     
    7865 
    7966        public Map<Object, Object> getParameters(); 
     67 
     68        public OCommandContext getContext(); 
    8069} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/command/OCommandExecutorAbstract.java

    r19299 r19635  
    3333        protected int                                                                   limit   = -1; 
    3434        protected Map<Object, Object>   parameters; 
     35        protected OCommandContext                       context; 
    3536 
    3637        public OCommandExecutorAbstract init(final String iText) { 
    3738                text = iText; 
    3839                return this; 
    39         } 
    40  
    41         /** 
    42          * Parse every time the request and execute it. 
    43          */ 
    44         public Object execute(final OCommandRequestText iRequest, final Map<Object, Object> iArgs) { 
    45                 parse(iRequest); 
    46                 return execute(iArgs); 
    4740        } 
    4841 
     
    7467        } 
    7568 
     69        public OCommandContext getContext() { 
     70                return context; 
     71        } 
     72 
    7673        public ODatabaseRecord getDatabase() { 
    7774                return ODatabaseRecordThreadLocal.INSTANCE.get(); 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/command/OCommandRequestTextAbstract.java

    r19299 r19635  
    2424import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal; 
    2525import com.orientechnologies.orient.core.exception.OSerializationException; 
     26import com.orientechnologies.orient.core.metadata.schema.OType; 
    2627import com.orientechnologies.orient.core.record.impl.ODocument; 
    2728import com.orientechnologies.orient.core.serialization.OMemoryStream; 
     
    142143                                        if (paramEntry.getValue() instanceof OCompositeKey) 
    143144                                                compositeKeyParams.put(paramEntry.getKey(), OCompositeKeySerializer.INSTANCE.toStream(paramEntry.getValue())); 
    144                                         else 
    145                                                 params.put(paramEntry.getKey(), paramEntry.getValue()); 
     145                                        else if(paramEntry.getValue() instanceof String) { 
     146            final StringBuilder builder = new StringBuilder(  ); 
     147            ORecordSerializerStringAbstract.simpleValueToStream( builder, OType.STRING, paramEntry.getValue() ); 
     148            params.put(paramEntry.getKey(), builder.toString()); 
     149          } 
     150          else 
     151            params.put(paramEntry.getKey(), paramEntry.getValue()); 
    146152 
    147153                                buffer.set(!params.isEmpty()); 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/config/OGlobalConfiguration.java

    r19431 r19635  
    2727import com.orientechnologies.common.profiler.OProfiler; 
    2828import com.orientechnologies.orient.core.OConstants; 
     29import com.orientechnologies.orient.core.cache.ODefaultCache; 
    2930import com.orientechnologies.orient.core.storage.fs.OMMapManager; 
    3031 
     
    6768        CACHE_LEVEL2_SIZE("cache.level2.size", "Size of the cache that keeps the record in memory", Integer.class, -1), 
    6869 
     70        CACHE_LEVEL2_IMPL("cache.level2.impl", "Actual implementation of secondary cache", String.class, ODefaultCache.class 
     71                        .getCanonicalName()), 
     72 
    6973        CACHE_LEVEL2_STRATEGY("cache.level2.strategy", 
    7074                        "Strategy to use when a database requests a record: 0 = pop the record, 1 = copy the record", Integer.class, 0, 
     
    242246                        }), 
    243247 
     248        PROFILER_AUTODUMP_INTERVAL("profiler.autoDump.interval", 
     249                        "Dumps the profiler values at regular intervals. Time is expressed in seconds", Integer.class, 0, 
     250                        new OConfigurationChangeCallback() { 
     251                                public void change(final Object iCurrentValue, final Object iNewValue) { 
     252                                        OProfiler.getInstance().setAutoDump((Integer) iNewValue); 
     253                                } 
     254                        }), 
     255 
     256        PROFILER_AUTODUMP_RESET("profiler.autoDump.reset", "Resets the profiler at every auto dump", Boolean.class, true, 
     257                        new OConfigurationChangeCallback() { 
     258                                public void change(final Object iCurrentValue, final Object iNewValue) { 
     259                                        OProfiler.getInstance().setAutoDumpReset((Boolean) iNewValue); 
     260                                } 
     261                        }), 
    244262        // LOG 
    245263        LOG_CONSOLE_LEVEL("log.console.level", "Console logging level", String.class, "info", new OConfigurationChangeCallback() { 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/config/OStorageConfiguration.java

    r19448 r19635  
    364364        public void close() throws IOException { 
    365365        } 
     366 
     367        public void setCluster(final OStorageClusterConfiguration config) { 
     368                while (config.getId() >= clusters.size()) 
     369                        clusters.add(null); 
     370                clusters.set(config.getId(), config); 
     371        } 
     372 
     373        public void dropCluster(final int iClusterId) { 
     374                if (iClusterId < clusters.size()) { 
     375                        clusters.set(iClusterId, null); 
     376                        update(); 
     377                } 
     378        } 
    366379} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/db/ODatabasePojoAbstract.java

    r19431 r19635  
    463463 
    464464        /** 
    465          * Convert an array of parameters: if a POJO is used, then replace it with its record id. 
     465         * Converts an array of parameters: if a POJO is used, then replace it with its record id. 
    466466         *  
    467467         * @param iArgs 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/db/ODatabasePoolBase.java

    r18649 r19635  
    5151 
    5252        public void close() { 
    53                 dbPool.close(); 
     53                if (dbPool != null) 
     54                        dbPool.close(); 
    5455        } 
    5556 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/db/ODatabaseSchemaAware.java

    r17050 r19635  
    2424public interface ODatabaseSchemaAware<T extends Object> extends ODatabaseComplex<T> { 
    2525        /** 
    26          * Creates a new entity instance. 
     26         * Creates a new entity instance. Each database implementation will return the right type. 
    2727         *  
    2828         * @return The new instance. 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/db/ODatabaseWrapperAbstract.java

    r19431 r19635  
    2121import java.util.concurrent.Callable; 
    2222 
     23import com.orientechnologies.orient.core.Orient; 
    2324import com.orientechnologies.orient.core.cache.OLevel1RecordCache; 
    2425import com.orientechnologies.orient.core.cache.OLevel2RecordCache; 
     
    4546        public <THISDB extends ODatabase> THISDB open(final String iUserName, final String iUserPassword) { 
    4647                underlying.open(iUserName, iUserPassword); 
     48                Orient.instance().getDatabaseFactory().register(databaseOwner); 
    4749                return (THISDB) this; 
    4850        } 
     
    5052        public <THISDB extends ODatabase> THISDB create() { 
    5153                underlying.create(); 
     54                Orient.instance().getDatabaseFactory().register(databaseOwner); 
    5255                return (THISDB) this; 
    5356        } 
     
    6366        public void close() { 
    6467                underlying.close(); 
     68                Orient.instance().getDatabaseFactory().unregister(databaseOwner); 
    6569        } 
    6670 
    6771        public void delete() { 
    68                 underlying.delete(); 
     72                underlying.drop(); 
     73                Orient.instance().getDatabaseFactory().unregister(databaseOwner); 
    6974        } 
    7075 
    7176        public void drop() { 
    7277                underlying.drop(); 
     78                Orient.instance().getDatabaseFactory().unregister(databaseOwner); 
    7379        } 
    7480 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/db/document/ODatabaseDocumentTx.java

    r19431 r19635  
    4242        } 
    4343 
     44        /** 
     45         * Creates a new ODocument. 
     46         */ 
    4447        @Override 
    4548        public ODocument newInstance() { 
    46                 return new ODocument(this); 
     49                return new ODocument(); 
    4750        } 
    4851 
    4952        public ODocument newInstance(final String iClassName) { 
    5053                checkSecurity(ODatabaseSecurityResources.CLASS, ORole.PERMISSION_CREATE, iClassName); 
    51                 return new ODocument(this, iClassName); 
     54                return new ODocument(iClassName); 
    5255        } 
    5356 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/db/graph/OGraphDatabase.java

    r19299 r19635  
    132132                        checkVertexClass(iClassName); 
    133133 
    134                 return new ODocument(this, iClassName).setOrdered(true); 
     134                return new ODocument(iClassName).setOrdered(true); 
    135135        } 
    136136 
     
    255255 
    256256                try { 
    257                         final ODocument edge = new ODocument(this, iClassName != null ? iClassName : EDGE_CLASS_NAME).setOrdered(true); 
     257                        final ODocument edge = new ODocument(iClassName != null ? iClassName : EDGE_CLASS_NAME).setOrdered(true); 
    258258                        edge.field(EDGE_FIELD_OUT, iOutVertex); 
    259259                        edge.field(EDGE_FIELD_IN, iInVertex); 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/db/graph/OGraphElement.java

    r18188 r19635  
    1717 
    1818import com.orientechnologies.orient.core.db.document.ODatabaseDocument; 
    19 import com.orientechnologies.orient.core.db.record.ODatabaseRecord; 
    2019import com.orientechnologies.orient.core.id.ORID; 
    2120import com.orientechnologies.orient.core.record.ORecordListener; 
     
    3534 
    3635        public OGraphElement(final ODatabaseGraphTx iDatabase, final ORID iRID) { 
    37                 this(iDatabase, new ODocument((ODatabaseRecord) iDatabase.getUnderlying(), iRID)); 
     36                this(iDatabase, new ODocument(iRID)); 
    3837                document.setTrackingChanges(false); 
    3938        } 
    4039 
    4140        public OGraphElement(final ODatabaseGraphTx iDatabase, final String iClassName) { 
    42                 this(iDatabase, new ODocument((ODatabaseRecord) iDatabase.getUnderlying(), iClassName)); 
     41                this(iDatabase, new ODocument(iClassName)); 
    4342                document.setTrackingChanges(false); 
    4443        } 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/db/object/ODatabaseObjectTx.java

    r19431 r19635  
    454454        public Object newInstance() { 
    455455                checkOpeness(); 
    456                 return new ODocument(underlying); 
     456                return new ODocument(); 
    457457        } 
    458458 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/db/object/OLazyObjectMap.java

    r19015 r19635  
    2424import com.orientechnologies.orient.core.db.ODatabasePojoAbstract; 
    2525import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal; 
    26 import com.orientechnologies.orient.core.db.record.ODatabaseRecord; 
    2726import com.orientechnologies.orient.core.record.ORecord; 
    2827import com.orientechnologies.orient.core.record.ORecordInternal; 
     
    7473                } else { 
    7574                        if (getDatabase().getRecordByUserObject(e, false) == null) { 
    76                                 underlying.put(iKey, getDatabase().pojo2Stream((TYPE) e, new ODocument((ODatabaseRecord) getDatabase().getUnderlying()))); 
     75                                underlying.put(iKey, getDatabase().pojo2Stream((TYPE) e, new ODocument())); 
    7776                        } else { 
    7877                                underlying.put(iKey, getDatabase().getRecordByUserObject(e, false)); 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/db/raw/ODatabaseRaw.java

    r19431 r19635  
    441441        @Override 
    442442        public String toString() { 
    443                 return "OrientDB[" + (getStorage() != null ? getStorage().getURL() : "?") + "]"; 
     443                final StringBuilder buffer = new StringBuilder(); 
     444                buffer.append("OrientDB["); 
     445                buffer.append(url != null ? url : "?"); 
     446                buffer.append(']'); 
     447                if (getStorage() != null) { 
     448                        buffer.append(" (users: "); 
     449                        buffer.append(getStorage().getUsers()); 
     450                        buffer.append(')'); 
     451                } 
     452                return buffer.toString(); 
    444453        } 
    445454 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/db/record/ODatabaseRecordAbstract.java

    r19448 r19635  
    1515 */ 
    1616package com.orientechnologies.orient.core.db.record; 
    17  
    18 import java.util.Arrays; 
    19 import java.util.Collections; 
    20 import java.util.HashSet; 
    21 import java.util.List; 
    22 import java.util.Locale; 
    23 import java.util.Set; 
    2417 
    2518import com.orientechnologies.common.exception.OException; 
     
    6255import com.orientechnologies.orient.core.tx.OTransactionRealAbstract; 
    6356 
     57import java.util.*; 
     58 
    6459@SuppressWarnings("unchecked") 
    6560public abstract class ODatabaseRecordAbstract extends ODatabaseWrapperAbstract<ODatabaseRaw> implements ODatabaseRecord { 
     
    8782 
    8883                recordType = iRecordType; 
    89                 level1Cache = new OLevel1RecordCache(this); 
     84                level1Cache = new OLevel1RecordCache(); 
    9085 
    9186                mvcc = OGlobalConfiguration.DB_MVCC.getValueAsBoolean(); 
     
    110105                        if (getStorage() instanceof OStorageEmbedded) { 
    111106                                user = getMetadata().getSecurity().authenticate(iUserName, iUserPassword); 
    112                                 final Set<ORole> roles = user.getRoles(); 
    113                                 if (roles == null || roles.isEmpty() || roles.iterator().next() == null) { 
    114                                         // SEEMS CORRUPTED: INSTALL DEFAULT ROLE 
    115                                         for (ODatabaseListener l : underlying.getListeners()) { 
    116                                                 if (l 
    117                                                                 .onCorruptionRepairDatabase(this, "Security metadata is broken: current user '" + user.getName() 
    118                                                                                 + "' has no roles defined", 
    119                                                                                 "The 'admin' user will be reinstalled with default role ('admin') and password 'admin'")) { 
    120                                                         user = null; 
    121                                                         user = metadata.getSecurity().repair(); 
    122                                                         break; 
     107                                if (user != null) { 
     108                                        final Set<ORole> roles = user.getRoles(); 
     109                                        if (roles == null || roles.isEmpty() || roles.iterator().next() == null) { 
     110                                                // SEEMS CORRUPTED: INSTALL DEFAULT ROLE 
     111                                                for (ODatabaseListener l : underlying.getListeners()) { 
     112                                                        if (l.onCorruptionRepairDatabase(this, "Security metadata is broken: current user '" + user.getName() 
     113                                                                        + "' has no roles defined", 
     114                                                                        "The 'admin' user will be reinstalled with default role ('admin') and password 'admin'")) { 
     115                                                                user = null; 
     116                                                                user = metadata.getSecurity().repair(); 
     117                                                                break; 
     118                                                        } 
    123119                                                } 
    124120                                        } 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/db/record/ORecordLazyList.java

    r19299 r19635  
    2828import com.orientechnologies.orient.core.id.ORecordId; 
    2929import com.orientechnologies.orient.core.record.ORecord; 
    30 import com.orientechnologies.orient.core.record.ORecordInternal; 
    3130import com.orientechnologies.orient.core.record.impl.ODocument; 
    3231import com.orientechnologies.orient.core.serialization.serializer.OStringSerializerHelper; 
     
    5554        } 
    5655 
    57         public ORecordLazyList(final ORecordInternal<?> iSourceRecord) { 
     56        public ORecordLazyList(final ODocument iSourceRecord) { 
    5857                super(iSourceRecord); 
    59                 this.recordType = iSourceRecord.getRecordType(); 
     58                if (iSourceRecord != null) { 
     59                        this.recordType = iSourceRecord.getRecordType(); 
     60                        if (!iSourceRecord.isLazyLoad()) 
     61                                // SET AS NON-LAZY LOAD THE COLLECTION TOO 
     62                                autoConvertToRecord = false; 
     63                } else 
     64                        this.recordType = ODocument.RECORD_TYPE; 
    6065        } 
    6166 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/db/record/ORecordLazyMap.java

    r19299 r19635  
    4040        private boolean                                                                                                                                                                 autoConvertToRecord     = true; 
    4141 
    42         public ORecordLazyMap(final ORecord<?> iSourceRecord) { 
     42        public ORecordLazyMap(final ODocument iSourceRecord) { 
    4343                super(iSourceRecord); 
    4444                this.recordType = ODocument.RECORD_TYPE; 
    4545        } 
    4646 
    47         public ORecordLazyMap(final ORecord<?> iSourceRecord, final byte iRecordType) { 
     47        public ORecordLazyMap(final ODocument iSourceRecord, final byte iRecordType) { 
    4848                super(iSourceRecord); 
    4949                this.recordType = iRecordType; 
     50 
     51                if (iSourceRecord != null) { 
     52                        if (!iSourceRecord.isLazyLoad()) 
     53                                // SET AS NON-LAZY LOAD THE COLLECTION TOO 
     54                                autoConvertToRecord = false; 
     55                } 
    5056        } 
    5157 
    5258        @Override 
    5359        public boolean containsValue(final Object o) { 
    54                 // convertLinks2Records(); 
    5560                return super.containsValue(o); 
    5661        } 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/db/record/ORecordLazySet.java

    r19299 r19635  
    2626import com.orientechnologies.orient.core.id.ORID; 
    2727import com.orientechnologies.orient.core.record.ORecord; 
    28 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2928import com.orientechnologies.orient.core.record.impl.ODocument; 
    3029 
     
    5655        } 
    5756 
    58         public ORecordLazySet(final ORecordInternal<?> iSourceRecord) { 
     57        public ORecordLazySet(final ODocument iSourceRecord) { 
    5958                delegate = new ORecordLazyList(iSourceRecord).setListener(this); 
    6059        } 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/db/tool/ODatabaseImport.java

    r19431 r19635  
    143143 
    144144                final ORecordId rid = new ORecordId(); 
    145                 final ODocument doc = new ODocument(database, rid); 
     145                final ODocument doc = new ODocument(rid); 
    146146                for (String recId : recordToDelete) { 
    147147                        doc.reset(); 
     
    173173                String value; 
    174174 
    175                 final ODocument doc = new ODocument(database); 
     175                final ODocument doc = new ODocument(); 
    176176 
    177177                // FORCE RELOADING 
     
    566566                                        int holes = (int) (record.getIdentity().getClusterPosition() - nextAvailablePos); 
    567567 
    568                                         ODocument tempRecord = new ODocument(database); 
     568                                        ODocument tempRecord = new ODocument(); 
    569569                                        for (int i = 0; i < holes; ++i) { 
    570570                                                tempRecord.reset(); 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/fetch/OFetchHelper.java

    r19015 r19635  
    1616package com.orientechnologies.orient.core.fetch; 
    1717 
     18import java.io.IOException; 
    1819import java.util.Collection; 
    1920import java.util.HashMap; 
     
    2223 
    2324import com.orientechnologies.common.log.OLogManager; 
    24 import com.orientechnologies.orient.core.exception.ORecordNotFoundException; 
    25 import com.orientechnologies.orient.core.metadata.schema.OClass; 
     25import com.orientechnologies.orient.core.db.record.ODatabaseRecord; 
     26import com.orientechnologies.orient.core.db.record.OIdentifiable; 
     27import com.orientechnologies.orient.core.id.ORID; 
     28import com.orientechnologies.orient.core.id.ORecordId; 
     29import com.orientechnologies.orient.core.record.ORecordInternal; 
     30import com.orientechnologies.orient.core.record.ORecordSchemaAware; 
    2631import com.orientechnologies.orient.core.record.impl.ODocument; 
    2732import com.orientechnologies.orient.core.serialization.serializer.OStringSerializerHelper; 
     33import com.orientechnologies.orient.core.type.tree.OMVRBTreeRIDSet; 
    2834 
    2935/** 
     
    3440 */ 
    3541public class OFetchHelper { 
    36         public static final String      ANY_FIELD       = "*"; 
     42        public static final String      ROOT_FETCH      = "*"; 
    3743 
    3844        public static Map<String, Integer> buildFetchPlan(final String iFetchPlan) { 
    39                 final Map<String, Integer> fetchPlan; 
     45                final Map<String, Integer> fetchPlan = new HashMap<String, Integer>(); 
    4046 
    4147                if (iFetchPlan != null) { 
     
    4349                        final List<String> planParts = OStringSerializerHelper.split(iFetchPlan, ' '); 
    4450                        if (!planParts.isEmpty()) { 
    45                                 fetchPlan = new HashMap<String, Integer>(); 
    4651 
    4752                                List<String> parts; 
     
    5156                                } 
    5257                        } else { 
    53                                 fetchPlan = null; 
     58                                fetchPlan.put(ROOT_FETCH, 0); 
    5459                        } 
    5560                } else 
    56                         fetchPlan = null; 
     61                        fetchPlan.put(ROOT_FETCH, 0); 
    5762 
    5863                return fetchPlan; 
    5964        } 
    6065 
    61         @SuppressWarnings("unchecked") 
    62         public static void fetch(final ODocument iRootRecord, final Object iUserObject, final String[] iFieldNames, 
    63                         final Map<String, Integer> iFetchPlan, final String iCurrentField, final int iCurrentLevel, final int iMaxFetch, 
    64                         final OFetchListener iListener) { 
    65  
    66                 if (iMaxFetch > -1 && iListener.size() >= iMaxFetch) 
    67                         // MAX FETCH SIZE REACHED: STOP TO FETCH AT ALL 
    68                         return; 
    69  
    70                 Object fieldValue; 
    71                 Integer depthLevel; 
    72                 final Integer anyFieldDepthLevel = (iFetchPlan != null && iFetchPlan.get(ANY_FIELD) != null) ? iFetchPlan.get(ANY_FIELD) 
    73                                 : Integer.valueOf(0); 
     66        public static void fetch(final ORecordInternal<?> iRootRecord, final Object iUserObject, final Map<String, Integer> iFetchPlan, 
     67                        final OFetchListener iListener, final OFetchContext iContext) { 
    7468                try { 
    75                         // BROWSE ALL THE DOCUMENT'S FIELDS 
    76                         for (String fieldName : iFieldNames) { 
    77                                 fieldValue = iRootRecord.field(fieldName); 
    78  
    79                                 if (fieldValue == null 
    80                                                 || !(fieldValue instanceof ODocument) 
    81                                                 && (!(fieldValue instanceof Collection<?>) || (!((Collection<?>) fieldValue).isEmpty() && !(((Collection<?>) fieldValue) 
    82                                                                 .iterator().next() instanceof ODocument))) 
    83                                                 && (!(fieldValue instanceof Map<?, ?>) || (!((Map<?, ?>) fieldValue).isEmpty() && !(((Map<?, ?>) fieldValue).values() 
    84                                                                 .iterator().next() instanceof ODocument)))) 
    85                                         // NULL NEITHER LINK, NOR COLLECTION OF LINKS OR MAP OF LINKS 
    86                                         continue; 
    87  
    88                                 depthLevel = getDepthLevel(iRootRecord, iFetchPlan, fieldName); 
    89  
    90                                 if (depthLevel == null) 
    91                                         // NO SPECIFIED: ASSIGN DEFAULT LEVEL TAKEN FROM * WILDCARD IF ANY 
    92                                         depthLevel = anyFieldDepthLevel; 
    93  
    94                                 if (depthLevel == 0) 
    95                                         // NO FETCH THIS FIELD PLEASE 
    96                                         continue; 
    97  
    98                                 if (depthLevel > -1 && iCurrentLevel >= depthLevel) 
    99                                         // MAX DEPTH REACHED: STOP TO FETCH THIS FIELD 
    100                                         continue; 
    101  
    102                                 Object userObject; 
    103                                 if (fieldValue instanceof ODocument) { 
    104                                         final ODocument linked = (ODocument) fieldValue; 
    105                                         try { 
    106                                                 userObject = iListener.fetchLinked(iRootRecord, iUserObject, fieldName, linked); 
    107                                                 if (userObject != null) 
    108                                                         // GO RECURSIVELY 
    109                                                         fetch(linked, userObject, linked.fieldNames(), iFetchPlan, fieldName, iCurrentLevel + 1, iMaxFetch, iListener); 
    110                                         } catch (ORecordNotFoundException e) { 
    111                                                 OLogManager.instance().error(null, "Linked record %s was not found", linked); 
    112                                         } 
    113  
    114                                 } else if (fieldValue instanceof Collection<?>) { 
    115                                         final Collection<ODocument> linked = (Collection<ODocument>) fieldValue; 
    116                                         userObject = iListener.fetchLinked(iRootRecord, iUserObject, fieldName, linked); 
    117                                         if (userObject != null) 
    118                                                 for (ODocument d : (Collection<ODocument>) userObject) { 
    119                                                         // GO RECURSIVELY 
    120                                                         if (d != null) 
    121                                                                 fetch(d, d, d.fieldNames(), iFetchPlan, fieldName, iCurrentLevel + 1, iMaxFetch, iListener); 
    122                                                 } 
    123                                 } else if (fieldValue instanceof Map<?, ?>) { 
    124                                         final Map<String, ODocument> linked = (Map<String, ODocument>) fieldValue; 
    125                                         userObject = iListener.fetchLinked(iRootRecord, iUserObject, fieldName, linked); 
    126                                         if (userObject != null) 
    127                                                 for (ODocument d : ((Map<String, ODocument>) userObject).values()) { 
    128                                                         // GO RECURSIVELY 
    129                                                         if (d != null) 
    130                                                                 fetch(d, d, d.fieldNames(), iFetchPlan, fieldName, iCurrentLevel + 1, iMaxFetch, iListener); 
    131                                                 } 
    132                                 } 
    133  
    134                                 if (iMaxFetch > -1 && iListener.size() >= iMaxFetch) 
    135                                         // MAX FETCH SIZE REACHED: STOP TO FETCH AT ALL 
    136                                         return; 
     69                        if (iRootRecord instanceof ORecordSchemaAware<?>) { 
     70                                // SCHEMA AWARE 
     71                                final ORecordSchemaAware<?> record = (ORecordSchemaAware<?>) iRootRecord; 
     72                                final Map<ORID, Integer> parsedRecords = new HashMap<ORID, Integer>(); 
     73                                parsedRecords.put(iRootRecord.getIdentity(), 0); 
     74 
     75                                processRecordRidMap(record, iFetchPlan, 0, 0, -1, parsedRecords, "", iContext); 
     76                                processRecord(record, iUserObject, iFetchPlan, 0, 0, -1, parsedRecords, "", iListener, iContext); 
    13777                        } 
    13878                } catch (Exception e) { 
     
    182122        } 
    183123 
    184         private static Integer getDepthLevel(final ODocument doc, final Map<String, Integer> iFetchPlan, final String iFieldName) { 
    185                 Integer depthLevel; 
    186  
    187                 if (iFetchPlan != null) { 
    188                         // GET THE FETCH PLAN FOR THE GENERIC FIELD IF SPECIFIED 
    189                         depthLevel = iFetchPlan.get(iFieldName); 
    190  
    191                         if (depthLevel == null) { 
    192                                 OClass cls = doc.getSchemaClass(); 
    193                                 while (cls != null && depthLevel == null) { 
    194                                         depthLevel = iFetchPlan.get(cls.getName() + "." + iFieldName); 
    195  
    196                                         if (depthLevel == null) 
    197                                                 cls = cls.getSuperClass(); 
    198                                 } 
    199                         } 
    200                 } else 
    201                         // INFINITE 
    202                         depthLevel = -1; 
    203  
    204                 return depthLevel; 
     124        private static int getDepthLevel(final Map<String, Integer> iFetchPlan, final String iFieldPath) { 
     125                Integer depthLevel = iFetchPlan.get(OFetchHelper.ROOT_FETCH); 
     126 
     127                for (String fieldFetchDefinition : iFetchPlan.keySet()) { 
     128                        if (iFieldPath.equals(fieldFetchDefinition)) { 
     129                                // GET THE FETCH PLAN FOR THE GENERIC FIELD IF SPECIFIED 
     130                                depthLevel = iFetchPlan.get(fieldFetchDefinition); 
     131                                break; 
     132                        } else if (fieldFetchDefinition.startsWith(iFieldPath)) { 
     133                                // SETS THE FETCH LEVEL TO 2 (LOADS ALL DOCUMENT FIELDS) 
     134                                depthLevel = 1; 
     135                                break; 
     136                        } 
     137                } 
     138 
     139                return depthLevel.intValue(); 
     140        } 
     141 
     142        public static void processRecordRidMap(final ORecordSchemaAware<?> record, Map<String, Integer> iFetchPlan, 
     143                        final int iCurrentLevel, final int iLevelFromRoot, final int iFieldDepthLevel, final Map<ORID, Integer> parsedRecords, 
     144                        final String iFieldPathFromRoot, final OFetchContext iContext) throws IOException { 
     145                if (iFetchPlan == null) 
     146                        return; 
     147 
     148                Object fieldValue; 
     149                for (String fieldName : record.fieldNames()) { 
     150                        final int depthLevel; 
     151                        String fieldPath = !iFieldPathFromRoot.isEmpty() ? iFieldPathFromRoot + "." + fieldName : fieldName; 
     152                        if (iFieldDepthLevel > -1) { 
     153                                depthLevel = iFieldDepthLevel; 
     154                        } else { 
     155                                depthLevel = getDepthLevel(iFetchPlan, fieldPath); 
     156                        } 
     157 
     158                        fieldValue = record.field(fieldName); 
     159                        if (fieldValue == null 
     160                                        || !(fieldValue instanceof OIdentifiable) 
     161                                        && (!(fieldValue instanceof Collection<?>) || ((Collection<?>) fieldValue).size() == 0 || !(((Collection<?>) fieldValue) 
     162                                                        .iterator().next() instanceof OIdentifiable)) 
     163                                        && (!(fieldValue instanceof Map<?, ?>) || ((Map<?, ?>) fieldValue).size() == 0 || !(((Map<?, ?>) fieldValue).values() 
     164                                                        .iterator().next() instanceof OIdentifiable))) { 
     165                                continue; 
     166                        } else { 
     167                                try { 
     168                                        if (!(fieldValue instanceof ODocument 
     169                                                        && (((ODocument) fieldValue).isEmbedded() || !((ODocument) fieldValue).getIdentity().isValid()) && iContext 
     170                                                        .fetchEmbeddedDocuments()) && !iFetchPlan.containsKey(fieldPath) && depthLevel > -1 && iCurrentLevel >= depthLevel) { 
     171                                                // MAX DEPTH REACHED: STOP TO FETCH THIS FIELD 
     172                                                continue; 
     173                                        } 
     174                                        fetchRidMap(record, iFetchPlan, fieldValue, fieldName, iCurrentLevel, iLevelFromRoot + 1, iFieldDepthLevel, 
     175                                                        parsedRecords, fieldPath, iContext); 
     176                                } catch (Exception e) { 
     177                                        e.printStackTrace(); 
     178                                        OLogManager.instance().error(null, "Fetching error on record %s", e, record.getIdentity()); 
     179                                } 
     180                        } 
     181                } 
     182        } 
     183 
     184        private static void fetchRidMap(final ORecordSchemaAware<?> iRootRecord, final Map<String, Integer> iFetchPlan, 
     185                        final Object fieldValue, final String fieldName, final int iCurrentLevel, final int iLevelFromRoot, 
     186                        final int iFieldDepthLevel, final Map<ORID, Integer> parsedRecords, final String iFieldPathFromRoot, 
     187                        final OFetchContext iContext) throws IOException { 
     188                if (fieldValue == null) { 
     189                        return; 
     190                } else if (fieldValue instanceof ODocument) { 
     191                        fetchDocumentRidMap(iFetchPlan, fieldValue, fieldName, iCurrentLevel, iLevelFromRoot, iFieldDepthLevel, parsedRecords, 
     192                                        iFieldPathFromRoot, iContext); 
     193                } else if (fieldValue instanceof Collection<?>) { 
     194                        fetchCollectionRidMap(iRootRecord.getDatabase(), iFetchPlan, fieldValue, fieldName, iCurrentLevel, iLevelFromRoot, 
     195                                        iFieldDepthLevel, parsedRecords, iFieldPathFromRoot, iContext); 
     196                } else if (fieldValue.getClass().isArray()) { 
     197                        fetchArrayRidMap(iFetchPlan, fieldValue, fieldName, iCurrentLevel, iLevelFromRoot, iFieldDepthLevel, parsedRecords, 
     198                                        iFieldPathFromRoot, iContext); 
     199                } else if (fieldValue instanceof Map<?, ?>) { 
     200                        fetchMapRidMap(iFetchPlan, fieldValue, fieldName, iCurrentLevel, iLevelFromRoot, iFieldDepthLevel, parsedRecords, 
     201                                        iFieldPathFromRoot, iContext); 
     202                } 
     203        } 
     204 
     205        private static void fetchDocumentRidMap(Map<String, Integer> iFetchPlan, Object fieldValue, String fieldName, 
     206                        final int iCurrentLevel, final int iLevelFromRoot, final int iFieldDepthLevel, final Map<ORID, Integer> parsedRecords, 
     207                        final String iFieldPathFromRoot, final OFetchContext iContext) throws IOException { 
     208                updateRidMap(iFetchPlan, (ODocument) fieldValue, iCurrentLevel, iLevelFromRoot, iFieldDepthLevel, parsedRecords, 
     209                                iFieldPathFromRoot, iContext); 
     210        } 
     211 
     212        @SuppressWarnings("unchecked") 
     213        private static void fetchCollectionRidMap(final ODatabaseRecord iDatabase, final Map<String, Integer> iFetchPlan, 
     214                        final Object fieldValue, final String fieldName, final int iCurrentLevel, final int iLevelFromRoot, 
     215                        final int iFieldDepthLevel, final Map<ORID, Integer> parsedRecords, final String iFieldPathFromRoot, 
     216                        final OFetchContext iContext) throws IOException { 
     217                final Collection<ODocument> linked = (Collection<ODocument>) fieldValue; 
     218                for (OIdentifiable d : linked) { 
     219                        // GO RECURSIVELY 
     220                        if (d instanceof ORecordId) 
     221                                d = iDatabase.load((ORecordId) d); 
     222 
     223                        updateRidMap(iFetchPlan, (ODocument) d, iCurrentLevel, iLevelFromRoot, iFieldDepthLevel, parsedRecords, iFieldPathFromRoot, 
     224                                        iContext); 
     225                } 
     226        } 
     227 
     228        private static void fetchArrayRidMap(final Map<String, Integer> iFetchPlan, final Object fieldValue, final String fieldName, 
     229                        final int iCurrentLevel, final int iLevelFromRoot, final int iFieldDepthLevel, final Map<ORID, Integer> parsedRecords, 
     230                        final String iFieldPathFromRoot, final OFetchContext iContext) throws IOException { 
     231                if (fieldValue instanceof ODocument[]) { 
     232                        final ODocument[] linked = (ODocument[]) fieldValue; 
     233                        for (ODocument d : linked) 
     234                                // GO RECURSIVELY 
     235                                updateRidMap(iFetchPlan, (ODocument) d, iCurrentLevel, iLevelFromRoot, iFieldDepthLevel, parsedRecords, iFieldPathFromRoot, 
     236                                                iContext); 
     237                } 
     238        } 
     239 
     240        @SuppressWarnings("unchecked") 
     241        private static void fetchMapRidMap(Map<String, Integer> iFetchPlan, Object fieldValue, String fieldName, final int iCurrentLevel, 
     242                        final int iLevelFromRoot, final int iFieldDepthLevel, final Map<ORID, Integer> parsedRecords, 
     243                        final String iFieldPathFromRoot, final OFetchContext iContext) throws IOException { 
     244                final Map<String, ODocument> linked = (Map<String, ODocument>) fieldValue; 
     245                for (ODocument d : (linked).values()) 
     246                        // GO RECURSIVELY 
     247                        updateRidMap(iFetchPlan, (ODocument) d, iCurrentLevel, iLevelFromRoot, iFieldDepthLevel, parsedRecords, iFieldPathFromRoot, 
     248                                        iContext); 
     249        } 
     250 
     251        private static void updateRidMap(final Map<String, Integer> iFetchPlan, final ODocument fieldValue, final int iCurrentLevel, 
     252                        final int iLevelFromRoot, final int iFieldDepthLevel, final Map<ORID, Integer> parsedRecords, 
     253                        final String iFieldPathFromRoot, final OFetchContext iContext) throws IOException { 
     254                final Integer fetchedLevel = parsedRecords.get(fieldValue.getIdentity()); 
     255                int currentLevel = iCurrentLevel + 1; 
     256                int fieldDepthLevel = iFieldDepthLevel; 
     257                if (iFetchPlan.containsKey(iFieldPathFromRoot)) { 
     258                        currentLevel = 1; 
     259                        fieldDepthLevel = iFetchPlan.get(iFieldPathFromRoot); 
     260                } 
     261                if (fetchedLevel == null) { 
     262                        parsedRecords.put(fieldValue.getIdentity(), iLevelFromRoot); 
     263                        processRecordRidMap(fieldValue, iFetchPlan, currentLevel, iLevelFromRoot, fieldDepthLevel, parsedRecords, iFieldPathFromRoot, 
     264                                        iContext); 
     265                } else if ((!fieldValue.getIdentity().isValid() && fetchedLevel < iLevelFromRoot) || fetchedLevel > iLevelFromRoot) { 
     266                        parsedRecords.put(fieldValue.getIdentity(), iLevelFromRoot); 
     267                        processRecordRidMap((ODocument) fieldValue, iFetchPlan, currentLevel, iLevelFromRoot, fieldDepthLevel, parsedRecords, 
     268                                        iFieldPathFromRoot, iContext); 
     269                } 
     270        } 
     271 
     272        private static void processRecord(final ORecordSchemaAware<?> record, final Object iUserObject, 
     273                        final Map<String, Integer> iFetchPlan, final int iCurrentLevel, final int iLevelFromRoot, final int iFieldDepthLevel, 
     274                        final Map<ORID, Integer> parsedRecords, final String iFieldPathFromRoot, final OFetchListener iListener, 
     275                        final OFetchContext iContext) throws IOException { 
     276 
     277                Object fieldValue; 
     278 
     279                iContext.onBeforeFetch(record); 
     280 
     281                for (String fieldName : record.fieldNames()) { 
     282                        String fieldPath = !iFieldPathFromRoot.isEmpty() ? iFieldPathFromRoot + "." + fieldName : fieldName; 
     283                        final int depthLevel; 
     284                        if (iFieldDepthLevel > -1) { 
     285                                depthLevel = iFieldDepthLevel; 
     286                        } else { 
     287                                depthLevel = getDepthLevel(iFetchPlan, fieldPath); 
     288                        } 
     289                        fieldValue = record.field(fieldName); 
     290                        if (fieldValue == null 
     291                                        || !(fieldValue instanceof OIdentifiable) 
     292                                        && (!(fieldValue instanceof Collection<?>) || ((Collection<?>) fieldValue).size() == 0 || !(((Collection<?>) fieldValue) 
     293                                                        .iterator().next() instanceof OIdentifiable)) 
     294                                        && (!(fieldValue instanceof Map<?, ?>) || ((Map<?, ?>) fieldValue).size() == 0 || !(((Map<?, ?>) fieldValue).values() 
     295                                                        .iterator().next() instanceof OIdentifiable))) { 
     296                                iContext.onBeforeStandardField(fieldValue, fieldName, iUserObject); 
     297                                iListener.processStandardField(record, fieldValue, fieldName, iContext); 
     298                                iContext.onAfterStandardField(fieldValue, fieldName, iUserObject); 
     299                        } else { 
     300                                try { 
     301                                        if (!(!(fieldValue instanceof ODocument) || (((ODocument) fieldValue).isEmbedded() || !((ODocument) fieldValue) 
     302                                                        .getIdentity().isValid()) && iContext.fetchEmbeddedDocuments()) 
     303                                                        && !iFetchPlan.containsKey(fieldPath) && depthLevel > -1 && iCurrentLevel > depthLevel) { 
     304                                                // MAX DEPTH REACHED: STOP TO FETCH THIS FIELD 
     305                                                continue; 
     306                                        } 
     307                                        fetch(record, iUserObject, iFetchPlan, fieldValue, fieldName, iCurrentLevel, iLevelFromRoot + 1, iFieldDepthLevel, 
     308                                                        parsedRecords, depthLevel, fieldPath, iListener, iContext); 
     309                                } catch (Exception e) { 
     310                                        e.printStackTrace(); 
     311                                        OLogManager.instance().error(null, "Fetching error on record %s", e, record.getIdentity()); 
     312                                } 
     313                        } 
     314                } 
     315 
     316                iContext.onAfterFetch(record); 
     317        } 
     318 
     319        private static void fetch(final ORecordSchemaAware<?> iRootRecord, final Object iUserObject, 
     320                        final Map<String, Integer> iFetchPlan, final Object fieldValue, final String fieldName, final int iCurrentLevel, 
     321                        final int iLevelFromRoot, final int iFieldDepthLevel, final Map<ORID, Integer> parsedRecords, final int depthLevel, 
     322                        final String iFieldPathFromRoot, final OFetchListener iListener, final OFetchContext iContext) throws IOException { 
     323 
     324                int currentLevel = iCurrentLevel + 1; 
     325                int fieldDepthLevel = iFieldDepthLevel; 
     326                if (iFetchPlan.containsKey(iFieldPathFromRoot)) { 
     327                        currentLevel = 0; 
     328                        fieldDepthLevel = iFetchPlan.get(iFieldPathFromRoot); 
     329                } 
     330                if (fieldValue == null) { 
     331                        iListener.processStandardField(iRootRecord, null, fieldName, iContext); 
     332                } else if (fieldValue instanceof OIdentifiable) { 
     333                        if (fieldValue instanceof ODocument && ((ODocument) fieldValue).getClassName() != null 
     334                                        && ((ODocument) fieldValue).getClassName().equals(OMVRBTreeRIDSet.OCLASS_NAME)) { 
     335                                fetchCollection(iRootRecord, iUserObject, iFetchPlan, fieldValue, fieldName, currentLevel, iLevelFromRoot, fieldDepthLevel, 
     336                                                parsedRecords, iFieldPathFromRoot, iListener, iContext); 
     337                        } else { 
     338                                fetchDocument(iRootRecord, iUserObject, iFetchPlan, (OIdentifiable) fieldValue, fieldName, currentLevel, iLevelFromRoot, 
     339                                                fieldDepthLevel, parsedRecords, iFieldPathFromRoot, iListener, iContext); 
     340                        } 
     341                } else if (fieldValue instanceof Collection<?>) { 
     342                        fetchCollection(iRootRecord, iUserObject, iFetchPlan, fieldValue, fieldName, currentLevel, iLevelFromRoot, fieldDepthLevel, 
     343                                        parsedRecords, iFieldPathFromRoot, iListener, iContext); 
     344                } else if (fieldValue.getClass().isArray()) { 
     345                        fetchArray(iRootRecord, iUserObject, iFetchPlan, fieldValue, fieldName, currentLevel, iLevelFromRoot, fieldDepthLevel, 
     346                                        parsedRecords, iFieldPathFromRoot, iListener, iContext); 
     347                } else if (fieldValue instanceof Map<?, ?>) { 
     348                        fetchMap(iRootRecord, iUserObject, iFetchPlan, fieldValue, fieldName, currentLevel, iLevelFromRoot, fieldDepthLevel, 
     349                                        parsedRecords, iFieldPathFromRoot, iListener, iContext); 
     350                } 
     351        } 
     352 
     353        @SuppressWarnings("unchecked") 
     354        private static void fetchMap(final ORecordSchemaAware<?> iRootRecord, final Object iUserObject, 
     355                        final Map<String, Integer> iFetchPlan, Object fieldValue, String fieldName, final int iCurrentLevel, 
     356                        final int iLevelFromRoot, final int iFieldDepthLevel, final Map<ORID, Integer> parsedRecords, 
     357                        final String iFieldPathFromRoot, final OFetchListener iListener, final OFetchContext iContext) throws IOException { 
     358                final Map<String, ODocument> linked = (Map<String, ODocument>) fieldValue; 
     359                iContext.onBeforeMap(iRootRecord, fieldName, iUserObject); 
     360                for (String key : (linked).keySet()) { 
     361                        ODocument d = linked.get(key); 
     362                        // GO RECURSIVELY 
     363                        final Integer fieldDepthLevel = parsedRecords.get(d.getIdentity()); 
     364                        if (!d.getIdentity().isValid() || (fieldDepthLevel != null && fieldDepthLevel.intValue() == iLevelFromRoot)) { 
     365                                removeParsedFromMap(parsedRecords, d); 
     366                                iContext.onBeforeDocument(d, key, iUserObject); 
     367                                final Object userObject = iListener.fetchLinkedMapEntry(iRootRecord, iUserObject, fieldName, key, d, iContext); 
     368                                processRecord(d, userObject, iFetchPlan, iCurrentLevel, iLevelFromRoot, iFieldDepthLevel, parsedRecords, 
     369                                                iFieldPathFromRoot, iListener, iContext); 
     370                                iContext.onAfterDocument(d, key, iUserObject); 
     371                        } else { 
     372                                iListener.parseLinked(iRootRecord, d, iUserObject, key, iContext); 
     373                        } 
     374                } 
     375                iContext.onAfterMap(iRootRecord, fieldName, iUserObject); 
     376        } 
     377 
     378        private static void fetchArray(final ORecordSchemaAware<?> iRootRecord, final Object iUserObject, 
     379                        final Map<String, Integer> iFetchPlan, Object fieldValue, String fieldName, final int iCurrentLevel, 
     380                        final int iLevelFromRoot, final int iFieldDepthLevel, final Map<ORID, Integer> parsedRecords, 
     381                        final String iFieldPathFromRoot, final OFetchListener iListener, final OFetchContext iContext) throws IOException { 
     382                if (fieldValue instanceof ODocument[]) { 
     383                        final ODocument[] linked = (ODocument[]) fieldValue; 
     384                        iContext.onBeforeArray(iRootRecord, fieldName, iUserObject, linked); 
     385                        for (ODocument d : linked) { 
     386                                // GO RECURSIVELY 
     387                                final Integer fieldDepthLevel = parsedRecords.get(d.getIdentity()); 
     388                                if (!d.getIdentity().isValid() || (fieldDepthLevel != null && fieldDepthLevel.intValue() == iLevelFromRoot)) { 
     389                                        removeParsedFromMap(parsedRecords, d); 
     390                                        iContext.onBeforeDocument(d, fieldName, iUserObject); 
     391                                        final Object userObject = iListener.fetchLinked(iRootRecord, iUserObject, fieldName, d, iContext); 
     392                                        processRecord(d, userObject, iFetchPlan, iCurrentLevel, iLevelFromRoot, iFieldDepthLevel, parsedRecords, 
     393                                                        iFieldPathFromRoot, iListener, iContext); 
     394                                        iContext.onAfterDocument(d, fieldName, iUserObject); 
     395                                } else { 
     396                                        iListener.parseLinked(iRootRecord, d, iUserObject, fieldName, iContext); 
     397                                } 
     398                        } 
     399                        iContext.onAfterArray(iRootRecord, fieldName, iUserObject); 
     400                } else { 
     401                        iListener.processStandardField(iRootRecord, fieldValue, fieldName, iContext); 
     402                } 
     403        } 
     404 
     405        @SuppressWarnings("unchecked") 
     406        private static void fetchCollection(final ORecordSchemaAware<?> iRootRecord, final Object iUserObject, 
     407                        final Map<String, Integer> iFetchPlan, final Object fieldValue, final String fieldName, final int iCurrentLevel, 
     408                        final int iLevelFromRoot, final int iFieldDepthLevel, final Map<ORID, Integer> parsedRecords, 
     409                        final String iFieldPathFromRoot, final OFetchListener iListener, final OFetchContext iContext) throws IOException { 
     410                final Collection<OIdentifiable> linked; 
     411                if (fieldValue instanceof ODocument) { 
     412                        linked = new OMVRBTreeRIDSet().fromDocument((ODocument) fieldValue); 
     413                } else { 
     414                        linked = (Collection<OIdentifiable>) fieldValue; 
     415                } 
     416 
     417                iContext.onBeforeCollection(iRootRecord, fieldName, iUserObject, linked); 
     418                for (OIdentifiable d : linked) { 
     419                        // GO RECURSIVELY 
     420                        final Integer fieldDepthLevel = parsedRecords.get(d.getIdentity()); 
     421                        if (!d.getIdentity().isValid() || (fieldDepthLevel != null && fieldDepthLevel.intValue() == iLevelFromRoot)) { 
     422                                removeParsedFromMap(parsedRecords, d); 
     423                                d = d.getRecord(); 
     424 
     425                                if (!(d instanceof ODocument)) { 
     426                                        iListener.processStandardField(null, d, fieldName, iContext); 
     427                                } else { 
     428                                        iContext.onBeforeDocument((ODocument) d, fieldName, iUserObject); 
     429                                        final Object userObject = iListener.fetchLinkedCollectionValue(iRootRecord, iUserObject, fieldName, (ODocument) d, 
     430                                                        iContext); 
     431                                        processRecord((ODocument) d, userObject, iFetchPlan, iCurrentLevel, iLevelFromRoot, iFieldDepthLevel, parsedRecords, 
     432                                                        iFieldPathFromRoot, iListener, iContext); 
     433                                        iContext.onAfterDocument((ODocument) d, fieldName, iUserObject); 
     434                                } 
     435                        } else { 
     436                                iListener.parseLinked(iRootRecord, d, iUserObject, fieldName, iContext); 
     437                        } 
     438                } 
     439                iContext.onAfterCollection(iRootRecord, fieldName, iUserObject); 
     440        } 
     441 
     442        private static void fetchDocument(final ORecordSchemaAware<?> iRootRecord, final Object iUserObject, 
     443                        final Map<String, Integer> iFetchPlan, final OIdentifiable fieldValue, final String fieldName, final int iCurrentLevel, 
     444                        final int iLevelFromRoot, final int iFieldDepthLevel, final Map<ORID, Integer> parsedRecords, 
     445                        final String iFieldPathFromRoot, final OFetchListener iListener, final OFetchContext iContext) throws IOException { 
     446                final Integer fieldDepthLevel = parsedRecords.get(fieldValue.getIdentity()); 
     447                if (!fieldValue.getIdentity().isValid() || (fieldDepthLevel != null && fieldDepthLevel.intValue() == iLevelFromRoot)) { 
     448                        removeParsedFromMap(parsedRecords, fieldValue); 
     449                        final ODocument linked = (ODocument) fieldValue; 
     450                        iContext.onBeforeDocument(linked, fieldName, iUserObject); 
     451                        Object userObject = iListener.fetchLinked(iRootRecord, iUserObject, fieldName, linked, iContext); 
     452                        processRecord(linked, userObject, iFetchPlan, iCurrentLevel, iLevelFromRoot, iFieldDepthLevel, parsedRecords, 
     453                                        iFieldPathFromRoot, iListener, iContext); 
     454                        iContext.onAfterDocument(iRootRecord, fieldName, iUserObject); 
     455                } else { 
     456                        iListener.parseLinked(iRootRecord, fieldValue, iUserObject, fieldName, iContext); 
     457                } 
     458        } 
     459 
     460        protected static void removeParsedFromMap(final Map<ORID, Integer> parsedRecords, OIdentifiable d) { 
     461                if (d.getIdentity().isValid()) 
     462                        parsedRecords.remove(d.getIdentity()); 
    205463        } 
    206464} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/fetch/OFetchListener.java

    r17050 r19635  
    1616package com.orientechnologies.orient.core.fetch; 
    1717 
    18 import com.orientechnologies.orient.core.record.impl.ODocument; 
     18import com.orientechnologies.orient.core.db.record.OIdentifiable; 
     19import com.orientechnologies.orient.core.exception.OFetchException; 
     20import com.orientechnologies.orient.core.record.ORecordSchemaAware; 
    1921 
    2022/** 
     
    3335         * @return null if the fetching must stop, otherwise the current field value 
    3436         */ 
    35         public Object fetchLinked(ODocument iRoot, Object iUserObject, String iFieldName, Object iLinked); 
     37        public Object fetchLinked(final ORecordSchemaAware<?> iRoot, final Object iUserObject, final String iFieldName, 
     38                        final ORecordSchemaAware<?> iLinked, final OFetchContext iContext) throws OFetchException; 
    3639 
    37         public int size(); 
     40        public void parseLinked(final ORecordSchemaAware<?> iRootRecord, final OIdentifiable iLinked, final Object iUserObject, 
     41                        final String iFieldName, final OFetchContext iContext) throws OFetchException; 
     42 
     43        public Object fetchLinkedMapEntry(final ORecordSchemaAware<?> iRoot, final Object iUserObject, final String iFieldName, 
     44                        final String iKey, final ORecordSchemaAware<?> iLinked, final OFetchContext iContext) throws OFetchException; 
     45 
     46        public Object fetchLinkedCollectionValue(final ORecordSchemaAware<?> iRoot, final Object iUserObject, final String iFieldName, 
     47                        final ORecordSchemaAware<?> iLinked, final OFetchContext iContext) throws OFetchException; 
     48 
     49        public void processStandardField(final ORecordSchemaAware<?> iRecord, final Object iFieldValue, final String iFieldName, 
     50                        final OFetchContext iContext) throws OFetchException; 
     51 
    3852} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/index/OIndexMVRBTreeAbstract.java

    r19448 r19635  
    107107 
    108108                        name = iName; 
    109                         configuration = new ODocument(iDatabase); 
     109                        configuration = new ODocument(); 
    110110 
    111111                        indexDefinition = iIndexDefinition; 
     
    147147                        final ORID rid = (ORID) iConfig.field(CONFIG_MAP_RID, ORID.class); 
    148148                        if (rid == null) 
    149                                 return null; 
     149                                throw new OIndexException("Error during deserialization of index definition: '" + CONFIG_MAP_RID + "' attribute is null"); 
    150150 
    151151                        configuration = iConfig; 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/index/OIndexManagerAbstract.java

    r19431 r19635  
    6060 
    6161        public OIndexManagerAbstract(final ODatabaseRecord iDatabase) { 
    62                 super(new ODocument(iDatabase)); 
     62                super(new ODocument()); 
    6363        } 
    6464 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/iterator/OObjectIteratorCluster.java

    r17050 r19635  
    5959        } 
    6060 
    61         public void setFetchPlan(String fetchPlan) { 
     61        public OObjectIteratorCluster<T> setFetchPlan(String fetchPlan) { 
    6262                this.fetchPlan = fetchPlan; 
     63                return this; 
    6364        } 
    6465} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/iterator/ORecordIteratorClass.java

    r19431 r19635  
    1616package com.orientechnologies.orient.core.iterator; 
    1717 
    18 import java.util.NoSuchElementException; 
    19  
    20 import com.orientechnologies.orient.core.db.record.ORecordOperation; 
    2118import com.orientechnologies.orient.core.db.record.ODatabaseRecord; 
    2219import com.orientechnologies.orient.core.db.record.ODatabaseRecordAbstract; 
    2320import com.orientechnologies.orient.core.metadata.schema.OClass; 
     21import com.orientechnologies.orient.core.record.ORecord; 
    2422import com.orientechnologies.orient.core.record.ORecordInternal; 
    2523import com.orientechnologies.orient.core.record.impl.ODocument; 
     
    3634 *          Record Type 
    3735 */ 
    38 public class ORecordIteratorClass<REC extends ORecordInternal<?>> extends ORecordIterator<REC> { 
     36public class ORecordIteratorClass<REC extends ORecordInternal<?>> extends ORecordIteratorClusters<REC> { 
    3937        protected final OClass  targetClass; 
    40         protected final int[]           clusterIds; 
    41         protected int                                           currentClusterIdx; 
    4238        protected boolean                               polymorphic; 
    4339 
     
    5349                clusterIds = polymorphic ? targetClass.getPolymorphicClusterIds() : targetClass.getClusterIds(); 
    5450 
    55                 currentClusterIdx = 0; // START FROM THE FIRST CLUSTER 
     51                config(); 
     52        } 
    5653 
    57                 updateClusterRange(); 
    58                 current.clusterPosition = firstClusterPosition - 1; 
     54        @SuppressWarnings("unchecked") 
     55        @Override 
     56        public REC next() { 
     57                return (REC) super.next().getRecord(); 
     58        } 
    5959 
    60                 totalAvailableRecords = database.countClusterElements(clusterIds); 
    61  
    62                 txEntries = iDatabase.getTransaction().getRecordEntriesByClass(iClassName); 
    63  
    64                 if (txEntries != null) 
    65                         // ADJUST TOTAL ELEMENT BASED ON CURRENT TRANSACTION'S ENTRIES 
    66                         for (ORecordOperation entry : txEntries) { 
    67                                 if (entry.getRecord().getIdentity().isTemporary()) 
    68                                         totalAvailableRecords++; 
    69                                 else if (entry.type == ORecordOperation.DELETED) 
    70                                         totalAvailableRecords--; 
    71                         } 
     60        @SuppressWarnings("unchecked") 
     61        @Override 
     62        public REC previous() { 
     63                return (REC) super.previous().getRecord(); 
    7264        } 
    7365 
    7466        @Override 
    75         public boolean hasPrevious() { 
    76                 checkDirection(false); 
    77  
    78                 if (limit > -1 && browsedRecords >= limit) 
    79                         // LIMIT REACHED 
    80                         return false; 
    81  
    82                 if (browsedRecords >= totalAvailableRecords) 
    83                         return false; 
    84  
    85                 if (liveUpdated) 
    86                         return current.clusterPosition > database.getStorage().getClusterDataRange(current.clusterId)[0]; 
    87  
    88                 // ITERATE UNTIL THE PREVIOUS GOOD RECORD 
    89                 while (currentClusterIdx > -1) { 
    90                         if (current.clusterPosition > firstClusterPosition) 
    91                                 return true; 
    92  
    93                         // CLUSTER EXHAUSTED, TRY WITH THE PREVIOUS ONE 
    94                         currentClusterIdx--; 
    95                         updateClusterRange(); 
    96                         current.clusterPosition = lastClusterPosition + 1; 
    97                 } 
    98  
    99                 // CHECK IN TX IF ANY 
    100                 return txEntries != null && txEntries.size() - (currentTxEntryPosition + 1) > 0; 
    101         } 
    102  
    103         public boolean hasNext() { 
    104                 checkDirection(true); 
    105  
    106                 if (limit > -1 && browsedRecords >= limit) 
    107                         // LIMIT REACHED 
    108                         return false; 
    109  
    110                 if (browsedRecords >= totalAvailableRecords) 
    111                         return false; 
    112  
    113                 // COMPUTE THE NUMBER OF RECORDS TO BROWSE 
    114                 if (liveUpdated) 
    115                         lastClusterPosition = database.getStorage().getClusterDataRange(current.clusterId)[1]; 
    116  
    117                 // ITERATE UNTIL THE NEXT GOOD RECORD 
    118                 while (currentClusterIdx < clusterIds.length) { 
    119                         final long recordsToBrowse = current.clusterPosition > -2 && lastClusterPosition > -1 ? lastClusterPosition 
    120                                         - current.clusterPosition : 0; 
    121  
    122                         if (recordsToBrowse > 0) 
    123                                 return true; 
    124  
    125                         // CLUSTER EXHAUSTED, TRY WITH THE NEXT ONE 
    126                         currentClusterIdx++; 
    127                         if (currentClusterIdx >= clusterIds.length) 
    128                                 break; 
    129                         updateClusterRange(); 
    130                         current.clusterPosition = firstClusterPosition - 1; 
    131                 } 
    132  
    133                 // CHECK IN TX IF ANY 
    134                 return txEntries != null && txEntries.size() - (currentTxEntryPosition + 1) > 0; 
    135         } 
    136  
    137         /** 
    138          * Return the element at the current position and move backward the cursor to the previous position available. 
    139          *  
    140          * @return the previous record found, otherwise the NoSuchElementException exception is thrown when no more records are found. 
    141          */ 
    142         @SuppressWarnings("unchecked") 
    143         @Override 
    144         public REC previous() { 
    145                 checkDirection(false); 
    146  
    147                 ORecordInternal<?> record = getRecord(); 
    148  
    149                 // ITERATE UNTIL THE PREVIOUS GOOD RECORD 
    150                 while (currentClusterIdx > -1) { 
    151  
    152                         // MOVE BACKWARD IN THE CURRENT CLUSTER 
    153                         while (hasPrevious()) { 
    154                                 if (record == null) 
    155                                         record = readCurrentRecord(null, -1); 
    156  
    157                                 if (record != null) 
    158                                         // FOUND 
    159                                         if (record instanceof ODocument) { 
    160                                                 final ODocument doc = (ODocument) record; 
    161                                                 if (targetClass.isSuperClassOf(doc.getSchemaClass())) 
    162                                                         return (REC) record; 
    163                                         } 
    164                         } 
    165  
    166                         // CLUSTER EXHAUSTED, TRY WITH THE PREVIOUS ONE 
    167                         currentClusterIdx--; 
    168                         updateClusterRange(); 
    169                         current.clusterPosition = lastClusterPosition + 1; 
    170                 } 
    171  
    172                 throw new NoSuchElementException(); 
    173         } 
    174  
    175         /** 
    176          * Return the element at the current position and move forward the cursor to the next position available. 
    177          *  
    178          * @return the next record found, otherwise the NoSuchElementException exception is thrown when no more records are found. 
    179          */ 
    180         @SuppressWarnings("unchecked") 
    181         public REC next() { 
    182                 checkDirection(true); 
    183  
    184                 ORecordInternal<?> record = getRecord(); 
    185  
    186                 // ITERATE UNTIL THE NEXT GOOD RECORD 
    187                 while (currentClusterIdx < clusterIds.length) { 
    188  
    189                         // MOVE FORWARD IN THE CURRENT CLUSTER 
    190                         while (hasNext()) { 
    191                                 record = getTransactionEntry(); 
    192                                 if (record == null) 
    193                                         record = readCurrentRecord(null, +1); 
    194  
    195                                 if (record != null) 
    196                                         // FOUND 
    197                                         if (record instanceof ODocument) { 
    198                                                 final ODocument doc = (ODocument) record; 
    199                                                 if (targetClass.isSuperClassOf(doc.getSchemaClass())) 
    200                                                         return (REC) record; 
    201                                         } 
    202                         } 
    203  
    204                         // CLUSTER EXHAUSTED, TRY WITH THE NEXT ONE 
    205                         currentClusterIdx++; 
    206                         if (currentClusterIdx >= clusterIds.length) 
    207                                 break; 
    208                         updateClusterRange(); 
    209                         current.clusterPosition = firstClusterPosition - 1; 
    210                 } 
    211  
    212                 record = getTransactionEntry(); 
    213                 if (record != null) 
    214                         return (REC) record; 
    215  
    216                 throw new NoSuchElementException(); 
     67        protected boolean include(final ORecord<?> record) { 
     68                return record instanceof ODocument && targetClass.isSuperClassOf(((ODocument) record).getSchemaClass()); 
    21769        } 
    21870 
     
    22072                return polymorphic; 
    22173        } 
    222  
    223         public ORecordInternal<?> current() { 
    224                 return readCurrentRecord(getRecord(), 0); 
    225         } 
    226  
    227         /** 
    228          * Move the iterator to the begin of the range. If no range was specified move to the first record of the cluster. 
    229          *  
    230          * @return The object itself 
    231          */ 
    232         @Override 
    233         public ORecordIterator<REC> begin() { 
    234                 currentClusterIdx = 0; 
    235                 current.clusterPosition = -1; 
    236                 return this; 
    237         } 
    238  
    239         /** 
    240          * Move the iterator to the end of the range. If no range was specified move to the last record of the cluster. 
    241          *  
    242          * @return The object itself 
    243          */ 
    244         @Override 
    245         public ORecordIterator<REC> last() { 
    246                 currentClusterIdx = clusterIds.length - 1; 
    247                 current.clusterPosition = liveUpdated ? database.countClusterElements(clusterIds[currentClusterIdx]) : lastClusterPosition + 1; 
    248                 return this; 
    249         } 
    250  
    251         /** 
    252          * Tell to the iterator that the upper limit must be checked at every cycle. Useful when concurrent deletes or additions change 
    253          * the size of the cluster while you're browsing it. Default is false. 
    254          *  
    255          * @param iLiveUpdated 
    256          *          True to activate it, otherwise false (default) 
    257          * @see #isLiveUpdated() 
    258          */ 
    259         @Override 
    260         public ORecordIterator<REC> setLiveUpdated(boolean iLiveUpdated) { 
    261                 super.setLiveUpdated(iLiveUpdated); 
    262  
    263                 // SET THE UPPER LIMIT TO -1 IF IT'S ENABLED 
    264                 lastClusterPosition = iLiveUpdated ? -1 : database.countClusterElements(current.clusterId); 
    265  
    266                 if (iLiveUpdated) { 
    267                         firstClusterPosition = -1; 
    268                         lastClusterPosition = -1; 
    269                 } else { 
    270                         updateClusterRange(); 
    271                 } 
    272  
    273                 return this; 
    274         } 
    275  
    276         /** 
    277          * Read the current record and increment the counter if the record was found. 
    278          *  
    279          * @param iRecord 
    280          * @return 
    281          */ 
    282         private ORecordInternal<?> readCurrentRecord(ORecordInternal<?> iRecord, final int iMovement) { 
    283                 if (limit > -1 && browsedRecords >= limit) 
    284                         // LIMIT REACHED 
    285                         return null; 
    286  
    287                 current.clusterPosition += iMovement; 
    288  
    289                 if (iRecord != null) { 
    290                         iRecord.setIdentity(current); 
    291                         iRecord = lowLevelDatabase.load(iRecord, fetchPlan); 
    292                 } else 
    293                         iRecord = lowLevelDatabase.load(current, fetchPlan); 
    294  
    295                 if (iRecord != null) { 
    296                         browsedRecords++; 
    297                         return iRecord; 
    298                 } 
    299  
    300                 return null; 
    301         } 
    302  
    303         protected void updateClusterRange() { 
    304                 current.clusterId = clusterIds[currentClusterIdx]; 
    305                 long[] range = database.getStorage().getClusterDataRange(current.clusterId); 
    306                 firstClusterPosition = range[0]; 
    307                 lastClusterPosition = range[1]; 
    308         } 
    30974} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/iterator/ORecordIteratorCluster.java

    r19431 r19635  
    1818import java.util.NoSuchElementException; 
    1919 
    20 import com.orientechnologies.orient.core.db.record.ORecordOperation; 
    2120import com.orientechnologies.orient.core.db.record.ODatabaseRecord; 
    2221import com.orientechnologies.orient.core.db.record.ODatabaseRecordAbstract; 
     22import com.orientechnologies.orient.core.db.record.ORecordOperation; 
    2323import com.orientechnologies.orient.core.id.ORID; 
    2424import com.orientechnologies.orient.core.record.ORecordInternal; 
     
    3333 *          Record Type 
    3434 */ 
    35 public class ORecordIteratorCluster<REC extends ORecordInternal<?>> extends ORecordIterator<REC> { 
     35public class ORecordIteratorCluster<REC extends ORecordInternal<?>> extends OIdentifiableIterator<REC> { 
    3636        protected long  rangeFrom; 
    3737        protected long  rangeTo; 
     
    5252                rangeTo = iRangeTo; 
    5353 
    54                 long[] range = database.getStorage().getClusterDataRange(current.clusterId); 
     54                final long[] range = database.getStorage().getClusterDataRange(current.clusterId); 
    5555                firstClusterPosition = range[0]; 
    5656 
    57     if(rangeTo > -1) 
    58                   lastClusterPosition = Math.min(rangeTo, range[1]); 
    59     else 
    60       lastClusterPosition = range[1]; 
     57                if (rangeTo > -1) 
     58                        lastClusterPosition = Math.min(rangeTo, range[1]); 
     59                else 
     60                        lastClusterPosition = range[1]; 
    6161 
    6262                totalAvailableRecords = database.countClusterElements(current.clusterId); 
     
    167167 
    168168        public ORecordInternal<?> current() { 
    169                 final ORecordInternal<?> record = getRecord(); 
    170                 return readCurrentRecord(record, 0); 
     169                return readCurrentRecord(getRecord(), 0); 
    171170        } 
    172171 
     
    177176         */ 
    178177        @Override 
    179         public ORecordIterator<REC> begin() { 
     178        public ORecordIteratorCluster<REC> begin() { 
    180179                current.clusterPosition = getRangeFrom(); 
    181180                return this; 
     
    188187         */ 
    189188        @Override 
    190         public ORecordIterator<REC> last() { 
     189        public ORecordIteratorCluster<REC> last() { 
    191190                current.clusterPosition = getRangeTo(); 
    192191                return this; 
     
    242241         */ 
    243242        @Override 
    244         public ORecordIterator<REC> setLiveUpdated(boolean iLiveUpdated) { 
     243        public ORecordIteratorCluster<REC> setLiveUpdated(boolean iLiveUpdated) { 
    245244                super.setLiveUpdated(iLiveUpdated); 
    246245 
     
    259258                return this; 
    260259        } 
    261  
    262         /** 
    263          * Read the current record and increment the counter if the record was found. 
    264          *  
    265          * @param iRecord 
    266          * @return 
    267          */ 
    268         private ORecordInternal<?> readCurrentRecord(ORecordInternal<?> iRecord, final int iMovement) { 
    269                 if (limit > -1 && browsedRecords >= limit) 
    270                         // LIMIT REACHED 
    271                         return null; 
    272  
    273                 current.clusterPosition += iMovement; 
    274  
    275                 if (iRecord != null) { 
    276                         iRecord.setIdentity(current); 
    277                         iRecord = lowLevelDatabase.load(iRecord, fetchPlan); 
    278                 } else 
    279                         iRecord = lowLevelDatabase.load(current, fetchPlan); 
    280  
    281                 if (iRecord != null) 
    282                         browsedRecords++; 
    283  
    284                 return iRecord; 
    285         } 
    286260} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/metadata/OMetadata.java

    r19299 r19635  
    149149         */ 
    150150        public void close() { 
    151                 indexManager.flush(); 
    152                 schema.close(); 
    153                 security.close(); 
     151                if (indexManager != null) 
     152                        indexManager.flush(); 
     153                if (schema != null) 
     154                        schema.close(); 
     155                if (security != null) 
     156                        security.close(); 
    154157        } 
    155158 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/metadata/schema/OClass.java

    r19431 r19635  
    3232public interface OClass extends Comparable<OClass> { 
    3333        public static enum ATTRIBUTES { 
    34                 NAME, SHORTNAME, SUPERCLASS, OVERSIZE 
     34                NAME, SHORTNAME, SUPERCLASS, OVERSIZE, STRICTMODE 
    3535        } 
    3636 
     
    4040 
    4141        public <T> T newInstance() throws InstantiationException, IllegalAccessException; 
     42 
     43        public boolean isStrictMode(); 
     44 
     45        public OClass setStrictMode(boolean iMode); 
    4246 
    4347        public OClass getSuperClass(); 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/metadata/schema/OClassImpl.java

    r19431 r19635  
    6464        protected String                                                                                                name; 
    6565        protected Class<?>                                                                                      javaClass; 
    66         protected int                                                                                                           fixedSize               = 0; 
    6766        protected final Map<String, OProperty>  properties      = new HashMap<String, OProperty>(); 
    6867 
     
    7473        protected float                                                                                                 overSize                = 0f; 
    7574        protected String                                                                                                shortName; 
     75        protected boolean                                                                                               strictMode      = false;                                                                                                                // @SINCE v1.0rc8 
    7676 
    7777        /** 
     
    8585         */ 
    8686        protected OClassImpl(final OSchemaShared iOwner) { 
    87                 document = new ODocument(getDatabase()); 
     87                document = new ODocument(); 
    8888                owner = iOwner; 
    8989        } 
     
    281281        } 
    282282 
    283         public int fixedSize() { 
    284                 return fixedSize; 
    285         } 
    286  
    287283        public boolean existsProperty(final String iPropertyName) { 
    288284                return properties.containsKey(iPropertyName.toLowerCase()); 
     
    316312                if (prop == null) 
    317313                        throw new OSchemaException("Property '" + iPropertyName + "' not found in class " + name + "'"); 
    318  
    319                 fixedSize -= prop.getType().size; 
    320314        } 
    321315 
     
    363357                shortName = document.field("shortName"); 
    364358                defaultClusterId = (Integer) document.field("defaultClusterId"); 
     359                if (document.containsField("strictMode")) 
     360                        strictMode = (Boolean) document.field("strictMode"); 
    365361 
    366362                if (document.field("overSize") != null) 
     
    401397                        document.field("clusterIds", clusterIds); 
    402398                        document.field("overSize", overSize); 
     399                        document.field("strictMode", strictMode); 
    403400 
    404401                        final Set<ODocument> props = new HashSet<ODocument>(); 
     
    537534                getDatabase().checkSecurity(ODatabaseSecurityResources.SCHEMA, ORole.PERMISSION_UPDATE); 
    538535                this.overSize = overSize; 
     536        } 
     537 
     538        public boolean isStrictMode() { 
     539                return strictMode; 
     540        } 
     541 
     542        public OClass setStrictMode(final boolean iStrict) { 
     543                getDatabase().checkSecurity(ODatabaseSecurityResources.SCHEMA, ORole.PERMISSION_UPDATE); 
     544                final String cmd = String.format("alter class %s strictmode %s", name, iStrict); 
     545                getDatabase().command(new OCommandSQL(cmd)).execute(); 
     546                setStrictModeInternal(iStrict); 
     547                return this; 
     548        } 
     549 
     550        public void setStrictModeInternal(final boolean iStrict) { 
     551                getDatabase().checkSecurity(ODatabaseSecurityResources.SCHEMA, ORole.PERMISSION_UPDATE); 
     552                this.strictMode = iStrict; 
    539553        } 
    540554 
     
    660674                case OVERSIZE: 
    661675                        return getOverSize(); 
     676                case STRICTMODE: 
     677                        return isStrictMode(); 
    662678                } 
    663679 
     
    684700                        setOverSizeInternal(Float.parseFloat(stringValue.replace(',', '.'))); 
    685701                        break; 
     702                case STRICTMODE: 
     703                        setStrictModeInternal(Boolean.parseBoolean(stringValue)); 
     704                        break; 
    686705                } 
    687706 
     
    708727                        setOverSize(Float.parseFloat(stringValue)); 
    709728                        break; 
     729                case STRICTMODE: 
     730                        setStrictMode(Boolean.parseBoolean(stringValue)); 
     731                        break; 
    710732                } 
    711733                return this; 
     
    751773 
    752774                properties.put(lowerName, prop); 
    753                 fixedSize += iType.size; 
    754775 
    755776                if (iLinkedType != null) 
     
    784805 
    785806                for (final String fieldToIndex : fields) { 
    786                         final String fieldName = extractFieldName( fieldToIndex ); 
     807                        final String fieldName = extractFieldName(fieldToIndex); 
    787808                        if (!existingFieldNames.contains(fieldName.toLowerCase())) 
    788809                                throw new OIndexException("Index with name : '" + iName + "' cannot be created on class : '" + name + "' because field: '" 
     
    794815                final OIndexDefinition indexDefinition; 
    795816                if (fieldsToIndex.size() == 1) { 
    796       indexDefinition = createSingleFieldIndexDefinition(fields[0] ); 
    797     } 
    798                 else { 
    799       indexDefinition = createMultipleFieldIndexDefinition( fieldsToIndex ); 
     817                        indexDefinition = createSingleFieldIndexDefinition(fields[0]); 
     818                } else { 
     819                        indexDefinition = createMultipleFieldIndexDefinition(fieldsToIndex); 
    800820                } 
    801821 
     
    805825        } 
    806826 
    807   private OIndexDefinition createMultipleFieldIndexDefinition( final List<String> fieldsToIndex ) 
    808   { 
    809     final OIndexDefinition indexDefinition; 
    810     final OCompositeIndexDefinition compositeIndex = new OCompositeIndexDefinition(name); 
    811  
    812     for (final String fieldName : fieldsToIndex) { 
    813       final OProperty propertyToIndex = properties.get(fieldName.toLowerCase()); 
    814       final OType propertyType = propertyToIndex.getType(); 
    815       if (propertyType.equals(OType.EMBEDDEDLIST) || propertyType.equals(OType.EMBEDDEDSET) || propertyType.equals(OType.LINKSET) 
    816           || propertyType.equals(OType.LINKSET) || propertyType.equals( OType.EMBEDDEDMAP ) || propertyType.equals( OType.LINKMAP )) 
    817         throw new OIndexException("Collections are not supported in composite indexes"); 
    818  
    819       final OPropertyIndexDefinition propertyIndex = new OPropertyIndexDefinition(name, propertyToIndex.getName(), propertyType); 
    820       compositeIndex.addIndex(propertyIndex); 
    821     } 
    822  
    823     indexDefinition = compositeIndex; 
    824     return indexDefinition; 
    825   } 
    826  
    827   private OIndexDefinition createSingleFieldIndexDefinition( final String field ) 
    828   { 
    829     final String fieldName = extractFieldName( field ); 
    830     final OIndexDefinition indexDefinition; 
    831   
    832     final OProperty propertyToIndex = properties.get(fieldName.toLowerCase()); 
    833     final OType propertyToIndexType = propertyToIndex.getType(); 
    834     final OType indexType; 
    835  
    836     if( propertyToIndexType == OType.EMBEDDEDMAP || propertyToIndexType == OType.LINKMAP) { 
    837       final OPropertyMapIndexDefinition.INDEX_BY indexBy = extractMapIndexSpecifier( field ); 
    838  
    839       if(indexBy.equals( OPropertyMapIndexDefinition.INDEX_BY.KEY )) 
    840         indexType = OType.STRING; 
    841       else { 
    842         if ( propertyToIndexType == OType.LINKMAP) 
    843           indexType = OType.LINK; 
    844         else { 
    845           indexType = propertyToIndex.getLinkedType(); 
    846           if(indexType == null) 
    847             throw new OIndexException("Linked type was not provided." + 
    848                     " You should provide linked type for embedded collections that are going to be indexed."); 
    849         } 
    850            
    851       } 
    852  
    853       indexDefinition = new OPropertyMapIndexDefinition(name, propertyToIndex.getName(), indexType, indexBy); 
    854     } else if ( propertyToIndexType.equals( OType.EMBEDDEDLIST ) || propertyToIndexType.equals( OType.EMBEDDEDSET ) || 
    855       propertyToIndexType.equals( OType.LINKLIST ) || propertyToIndexType.equals( OType.LINKSET )) { 
    856       if(propertyToIndexType.equals( OType.LINKLIST ) || propertyToIndexType.equals( OType.LINKSET )) 
    857         indexType = OType.LINK; 
    858       else  { 
    859         indexType = propertyToIndex.getLinkedType(); 
    860         if(indexType == null) 
    861           throw new OIndexException("Linked type was not provided." + 
    862                   " You should provide linked type for embedded collections that are going to be indexed."); 
    863       } 
    864  
    865        
    866       indexDefinition = new OPropertyListIndexDefinition(name, propertyToIndex.getName(), indexType); 
    867     } else  
    868       indexDefinition = new OPropertyIndexDefinition( name, propertyToIndex.getName(), propertyToIndexType ); 
    869     return indexDefinition; 
    870   } 
    871  
    872   public boolean areIndexed(final String... fields) { 
     827        private OIndexDefinition createMultipleFieldIndexDefinition(final List<String> fieldsToIndex) { 
     828                final OIndexDefinition indexDefinition; 
     829                final OCompositeIndexDefinition compositeIndex = new OCompositeIndexDefinition(name); 
     830 
     831                for (final String fieldName : fieldsToIndex) { 
     832                        final OProperty propertyToIndex = properties.get(fieldName.toLowerCase()); 
     833                        final OType propertyType = propertyToIndex.getType(); 
     834                        if (propertyType.equals(OType.EMBEDDEDLIST) || propertyType.equals(OType.EMBEDDEDSET) || propertyType.equals(OType.LINKSET) 
     835                                        || propertyType.equals(OType.LINKSET) || propertyType.equals(OType.EMBEDDEDMAP) || propertyType.equals(OType.LINKMAP)) 
     836                                throw new OIndexException("Collections are not supported in composite indexes"); 
     837 
     838                        final OPropertyIndexDefinition propertyIndex = new OPropertyIndexDefinition(name, propertyToIndex.getName(), propertyType); 
     839                        compositeIndex.addIndex(propertyIndex); 
     840                } 
     841 
     842                indexDefinition = compositeIndex; 
     843                return indexDefinition; 
     844        } 
     845 
     846        private OIndexDefinition createSingleFieldIndexDefinition(final String field) { 
     847                final String fieldName = extractFieldName(field); 
     848                final OIndexDefinition indexDefinition; 
     849 
     850                final OProperty propertyToIndex = properties.get(fieldName.toLowerCase()); 
     851                final OType propertyToIndexType = propertyToIndex.getType(); 
     852                final OType indexType; 
     853 
     854                if (propertyToIndexType == OType.EMBEDDEDMAP || propertyToIndexType == OType.LINKMAP) { 
     855                        final OPropertyMapIndexDefinition.INDEX_BY indexBy = extractMapIndexSpecifier(field); 
     856 
     857                        if (indexBy.equals(OPropertyMapIndexDefinition.INDEX_BY.KEY)) 
     858                                indexType = OType.STRING; 
     859                        else { 
     860                                if (propertyToIndexType == OType.LINKMAP) 
     861                                        indexType = OType.LINK; 
     862                                else { 
     863                                        indexType = propertyToIndex.getLinkedType(); 
     864                                        if (indexType == null) 
     865                                                throw new OIndexException("Linked type was not provided." 
     866                                                                + " You should provide linked type for embedded collections that are going to be indexed."); 
     867                                } 
     868 
     869                        } 
     870 
     871                        indexDefinition = new OPropertyMapIndexDefinition(name, propertyToIndex.getName(), indexType, indexBy); 
     872                } else if (propertyToIndexType.equals(OType.EMBEDDEDLIST) || propertyToIndexType.equals(OType.EMBEDDEDSET) 
     873                                || propertyToIndexType.equals(OType.LINKLIST) || propertyToIndexType.equals(OType.LINKSET)) { 
     874                        if (propertyToIndexType.equals(OType.LINKLIST) || propertyToIndexType.equals(OType.LINKSET)) 
     875                                indexType = OType.LINK; 
     876                        else { 
     877                                indexType = propertyToIndex.getLinkedType(); 
     878                                if (indexType == null) 
     879                                        throw new OIndexException("Linked type was not provided." 
     880                                                        + " You should provide linked type for embedded collections that are going to be indexed."); 
     881                        } 
     882 
     883                        indexDefinition = new OPropertyListIndexDefinition(name, propertyToIndex.getName(), indexType); 
     884                } else 
     885                        indexDefinition = new OPropertyIndexDefinition(name, propertyToIndex.getName(), propertyToIndexType); 
     886                return indexDefinition; 
     887        } 
     888 
     889        public boolean areIndexed(final String... fields) { 
    873890                return areIndexed(Arrays.asList(fields)); 
    874891        } 
     
    930947        } 
    931948 
    932   private String extractFieldName(final String fieldName) { 
    933     String[] fieldNameParts = fieldName.split( "\\s+" ); 
    934     if(fieldNameParts.length == 1) 
    935       return fieldName; 
    936     if(fieldNameParts.length == 3) 
    937       return fieldNameParts[0]; 
    938  
    939     throw new IllegalArgumentException( "Illegal field name format, should be '<property> [by key|value]' but was '" + fieldName + "'" ); 
    940   } 
    941  
    942   private OPropertyMapIndexDefinition.INDEX_BY extractMapIndexSpecifier(final String fieldName) { 
    943     String[] fieldNameParts = fieldName.split( "\\s+" ); 
    944     if(fieldNameParts.length == 1) 
    945       return OPropertyMapIndexDefinition.INDEX_BY.KEY; 
    946  
    947     if(fieldNameParts.length == 3) { 
    948       if("by".equals(fieldNameParts[1].toLowerCase())) 
    949         try{ 
    950           return OPropertyMapIndexDefinition.INDEX_BY.valueOf( fieldNameParts[2].toUpperCase() ); 
    951         } catch( IllegalArgumentException iae ) { 
    952           throw new IllegalArgumentException( "Illegal field name format, should be '<property> [by key|value]' but was '" + fieldName + "'"); 
    953         } 
    954     } 
    955  
    956     throw new IllegalArgumentException( "Illegal field name format, should be '<property> [by key|value]' but was '" + fieldName + "'" ); 
    957   } 
     949        private String extractFieldName(final String fieldName) { 
     950                String[] fieldNameParts = fieldName.split("\\s+"); 
     951                if (fieldNameParts.length == 1) 
     952                        return fieldName; 
     953                if (fieldNameParts.length == 3) 
     954                        return fieldNameParts[0]; 
     955 
     956                throw new IllegalArgumentException("Illegal field name format, should be '<property> [by key|value]' but was '" + fieldName 
     957                                + "'"); 
     958        } 
     959 
     960        private OPropertyMapIndexDefinition.INDEX_BY extractMapIndexSpecifier(final String fieldName) { 
     961                String[] fieldNameParts = fieldName.split("\\s+"); 
     962                if (fieldNameParts.length == 1) 
     963                        return OPropertyMapIndexDefinition.INDEX_BY.KEY; 
     964 
     965                if (fieldNameParts.length == 3) { 
     966                        if ("by".equals(fieldNameParts[1].toLowerCase())) 
     967                                try { 
     968                                        return OPropertyMapIndexDefinition.INDEX_BY.valueOf(fieldNameParts[2].toUpperCase()); 
     969                                } catch (IllegalArgumentException iae) { 
     970                                        throw new IllegalArgumentException("Illegal field name format, should be '<property> [by key|value]' but was '" 
     971                                                        + fieldName + "'"); 
     972                                } 
     973                } 
     974 
     975                throw new IllegalArgumentException("Illegal field name format, should be '<property> [by key|value]' but was '" + fieldName 
     976                                + "'"); 
     977        } 
    958978 
    959979        private void setPolymorphicClusterIds(final int[] iClusterIds) { 
     
    962982        } 
    963983 
    964         private void setClusterIds(final int[] iClusterIds) { 
     984        private OClass setClusterIds(final int[] iClusterIds) { 
    965985                clusterIds = iClusterIds; 
    966986                Arrays.sort(clusterIds); 
     987                return this; 
    967988        } 
    968989} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/metadata/schema/OType.java

    r19431 r19635  
    1717 
    1818import java.lang.reflect.Array; 
     19import java.math.BigDecimal; 
    1920import java.text.ParseException; 
    2021import java.util.Collection; 
     
    4142 */ 
    4243public enum OType { 
    43         BOOLEAN("Boolean", 0, true, 1, new Class<?>[] { Boolean.class, Boolean.TYPE }, new Class<?>[] { Boolean.class, Number.class }) { 
    44         }, 
    45         INTEGER("Integer", 1, true, 4, new Class<?>[] { Integer.class, Integer.TYPE }, new Class<?>[] { Integer.class, Number.class }) { 
    46         }, 
    47         SHORT("Short", 2, true, 2, new Class<?>[] { Short.class, Short.TYPE }, new Class<?>[] { Short.class, Number.class }) { 
    48         }, 
    49         LONG("Long", 3, true, 8, new Class<?>[] { Long.class, Long.TYPE }, new Class<?>[] { Long.class, Number.class, }) { 
    50         }, 
    51         FLOAT("Float", 4, true, 4, new Class<?>[] { Float.class, Float.TYPE }, new Class<?>[] { Float.class, Number.class }) { 
    52         }, 
    53         DOUBLE("Double", 5, true, 8, new Class<?>[] { Double.class, Double.TYPE }, new Class<?>[] { Double.class, Number.class }) { 
    54         }, 
    55         DATETIME("Datetime", 6, true, 8, new Class<?>[] { Date.class }, new Class<?>[] { Date.class, Number.class }) { 
    56         }, 
    57         STRING("String", 7, false, 8, new Class<?>[] { String.class }, new Class<?>[] { String.class }) { 
    58         }, 
    59         BINARY("Binary", 8, false, 8, new Class<?>[] { Array.class }, new Class<?>[] { Array.class }) { 
    60         }, 
    61         EMBEDDED("Embedded", 9, false, 8, new Class<?>[] { Object.class }, new Class<?>[] { OSerializableStream.class }) { 
    62         }, 
    63         EMBEDDEDLIST("EmbeddedList", 10, false, 8, new Class<?>[] { List.class }, new Class<?>[] { List.class }) { 
    64         }, 
    65         EMBEDDEDSET("EmbeddedSet", 11, false, 8, new Class<?>[] { Set.class }, new Class<?>[] { Set.class }) { 
    66         }, 
    67         EMBEDDEDMAP("EmbeddedMap", 12, false, 8, new Class<?>[] { Map.class }, new Class<?>[] { Map.class }) { 
    68         }, 
    69         LINK("Link", 13, true, 8, new Class<?>[] { Object.class, ORecordId.class }, new Class<?>[] { ORecord.class, ORID.class  }) { 
    70         }, 
    71         LINKLIST("LinkList", 14, false, 8, new Class<?>[] { List.class }, new Class<?>[] { List.class }) { 
    72         }, 
    73         LINKSET("LinkSet", 15, false, 8, new Class<?>[] { Set.class }, new Class<?>[] { Set.class }) { 
    74         }, 
    75         LINKMAP("LinkMap", 16, false, 8, new Class<?>[] { Map.class }, new Class<?>[] { Map.class }) { 
    76         }, 
    77         BYTE("Byte", 17, true, 1, new Class<?>[] { Byte.class, Byte.TYPE }, new Class<?>[] { Byte.class, Number.class }) { 
    78         }, 
    79         TRANSIENT("Transient", 18, true, 0, new Class<?>[] {}, new Class<?>[] {}) { 
    80         }, 
    81         DATE("Date", 19, true, 8, new Class<?>[] { Date.class }, new Class<?>[] { Date.class, Number.class }) { 
    82         }, 
    83         CUSTOM("Custom", 20, false, 8, new Class<?>[] { OSerializableStream.class }, new Class<?>[] { OSerializableStream.class }) { 
     44        BOOLEAN("Boolean", 0, new Class<?>[] { Boolean.class, Boolean.TYPE }, new Class<?>[] { Boolean.class, Number.class }) { 
     45        }, 
     46        INTEGER("Integer", 1, new Class<?>[] { Integer.class, Integer.TYPE }, new Class<?>[] { Integer.class, Number.class }) { 
     47        }, 
     48        SHORT("Short", 2, new Class<?>[] { Short.class, Short.TYPE }, new Class<?>[] { Short.class, Number.class }) { 
     49        }, 
     50        LONG("Long", 3, new Class<?>[] { Long.class, Long.TYPE }, new Class<?>[] { Long.class, Number.class, }) { 
     51        }, 
     52        FLOAT("Float", 4, new Class<?>[] { Float.class, Float.TYPE }, new Class<?>[] { Float.class, Number.class }) { 
     53        }, 
     54        DOUBLE("Double", 5, new Class<?>[] { Double.class, Double.TYPE }, new Class<?>[] { Double.class, Number.class }) { 
     55        }, 
     56        DATETIME("Datetime", 6, new Class<?>[] { Date.class }, new Class<?>[] { Date.class, Number.class }) { 
     57        }, 
     58        STRING("String", 7, new Class<?>[] { String.class }, new Class<?>[] { String.class }) { 
     59        }, 
     60        BINARY("Binary", 8, new Class<?>[] { Array.class }, new Class<?>[] { Array.class }) { 
     61        }, 
     62        EMBEDDED("Embedded", 9, new Class<?>[] { Object.class }, new Class<?>[] { OSerializableStream.class }) { 
     63        }, 
     64        EMBEDDEDLIST("EmbeddedList", 10, new Class<?>[] { List.class }, new Class<?>[] { List.class }) { 
     65        }, 
     66        EMBEDDEDSET("EmbeddedSet", 11, new Class<?>[] { Set.class }, new Class<?>[] { Set.class }) { 
     67        }, 
     68        EMBEDDEDMAP("EmbeddedMap", 12, new Class<?>[] { Map.class }, new Class<?>[] { Map.class }) { 
     69        }, 
     70        LINK("Link", 13, new Class<?>[] { Object.class, ORecordId.class }, new Class<?>[] { ORecord.class, ORID.class }) { 
     71        }, 
     72        LINKLIST("LinkList", 14, new Class<?>[] { List.class }, new Class<?>[] { List.class }) { 
     73        }, 
     74        LINKSET("LinkSet", 15, new Class<?>[] { Set.class }, new Class<?>[] { Set.class }) { 
     75        }, 
     76        LINKMAP("LinkMap", 16, new Class<?>[] { Map.class }, new Class<?>[] { Map.class }) { 
     77        }, 
     78        BYTE("Byte", 17, new Class<?>[] { Byte.class, Byte.TYPE }, new Class<?>[] { Byte.class, Number.class }) { 
     79        }, 
     80        TRANSIENT("Transient", 18, new Class<?>[] {}, new Class<?>[] {}) { 
     81        }, 
     82        DATE("Date", 19, new Class<?>[] { Date.class }, new Class<?>[] { Date.class, Number.class }) { 
     83        }, 
     84        CUSTOM("Custom", 20, new Class<?>[] { OSerializableStream.class }, new Class<?>[] { OSerializableStream.class }) { 
     85        }, 
     86        DECIMAL("Decimal", 21, new Class<?>[] { BigDecimal.class }, new Class<?>[] { BigDecimal.class, Number.class }) { 
    8487        }; 
    8588 
    8689        protected static final OType[]  TYPES   = new OType[] { STRING, BOOLEAN, BYTE, INTEGER, SHORT, LONG, FLOAT, DOUBLE, DATE, DATETIME, 
    87                         BINARY, EMBEDDEDLIST, EMBEDDEDSET, EMBEDDEDMAP, LINK, LINKLIST, LINKSET, LINKMAP, EMBEDDED, CUSTOM, TRANSIENT }; 
     90                        BINARY, EMBEDDEDLIST, EMBEDDEDSET, EMBEDDEDMAP, LINK, LINKLIST, LINKSET, LINKMAP, EMBEDDED, CUSTOM, TRANSIENT, DECIMAL }; 
    8891 
    8992        protected String                                                                name; 
    9093        protected int                                                                           id; 
    91         protected boolean                                                               fixedSize; 
    92         protected int                                                                           size; 
    9394        protected Class<?>[]                                            javaTypes; 
    9495        protected Class<?>[]                                            allowAssignmentFrom; 
    9596 
    96         private OType(final String iName, final int iId, final boolean iFixedSize, final int iSize, final Class<?>[] iJavaTypes, 
    97                         final Class<?>[] iAllowAssignmentBy) { 
     97        private OType(final String iName, final int iId, final Class<?>[] iJavaTypes, final Class<?>[] iAllowAssignmentBy) { 
    9898                name = iName; 
    9999                id = iId; 
    100                 fixedSize = iFixedSize; 
    101                 size = iSize; 
    102100                javaTypes = iJavaTypes; 
    103101                allowAssignmentFrom = iAllowAssignmentBy; 
     
    327325                                else 
    328326                                        return ((Number) iValue).floatValue(); 
     327 
     328                        } else if (iTargetClass.equals(BigDecimal.class)) { 
     329                                if (iValue instanceof BigDecimal) 
     330                                        return iValue; 
     331                                else if (iValue instanceof String) 
     332                                        return new BigDecimal((String) iValue); 
     333                                else if (iValue instanceof Number) 
     334                                        return new BigDecimal(iValue.toString()); 
    329335 
    330336                        } else if (iTargetClass.equals(Double.TYPE) || iTargetClass.equals(Double.class)) { 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/query/OQueryHelper.java

    r19015 r19635  
    1818public class OQueryHelper { 
    1919        protected static final String   WILDCARD_ANYCHAR        = "?"; 
    20         protected static final String   WILDCARD_ANY            = "%"; 
     20        protected static final String   WILDCARD_ANY                    = "%"; 
    2121 
    2222        public static boolean like(final String currentValue, String iValue) { 
     
    5151                        iValue = iValue.substring(0, iValue.length() - WILDCARD_ANY.length()); 
    5252                        return value.startsWith(iValue); 
     53 
     54                } else { 
     55                        final int pos = iValue.indexOf(WILDCARD_ANY); 
     56                        if (pos > -1) { 
     57                                // XX%XXX 
     58                                return value.startsWith(iValue.substring(0, pos)) && value.endsWith(iValue.substring(pos + 1)); 
     59                        } 
    5360                } 
    5461 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/query/nativ/ONativeAsynchQuery.java

    r19299 r19635  
    2121import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal; 
    2222import com.orientechnologies.orient.core.db.record.ODatabaseRecord; 
     23import com.orientechnologies.orient.core.db.record.ODatabaseRecordAbstract; 
     24import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2325import com.orientechnologies.orient.core.exception.OCommandExecutionException; 
     26import com.orientechnologies.orient.core.iterator.ORecordIteratorClass; 
    2427import com.orientechnologies.orient.core.metadata.schema.OClass; 
    2528import com.orientechnologies.orient.core.record.ORecordInternal; 
    2629import com.orientechnologies.orient.core.record.impl.ODocument; 
    27 import com.orientechnologies.orient.core.storage.ORecordBrowsingListener; 
    2830import com.orientechnologies.orient.core.storage.OStorageEmbedded; 
    2931 
    3032@SuppressWarnings("serial") 
    31 public abstract class ONativeAsynchQuery<CTX extends OQueryContextNative> extends ONativeQuery<CTX> implements 
    32                 ORecordBrowsingListener { 
     33public abstract class ONativeAsynchQuery<CTX extends OQueryContextNative> extends ONativeQuery<CTX> { 
    3334        protected OCommandResultListener        resultListener; 
    3435        protected int                                                                                   resultCount     = 0; 
     
    8081 
    8182                // CHECK IF A CLASS WAS CREATED 
    82                 final OClass cls = database.getMetadata().getSchema().getClass(cluster); 
     83                final OClass cls = database.getMetadata().getSchema().getClass(className); 
    8384                if (cls == null) 
    84                         throw new OCommandExecutionException("Cluster " + cluster + " was not found"); 
     85                        throw new OCommandExecutionException("Class '" + className + "' was not found"); 
    8586 
    86                 ((OStorageEmbedded) database.getStorage()).browse(cls.getPolymorphicClusterIds(), null, null, this, record, false); 
     87                final ORecordIteratorClass<ORecordInternal<?>> target = new ORecordIteratorClass<ORecordInternal<?>>(database, 
     88                                (ODatabaseRecordAbstract) database, className, isPolymorphic()); 
     89 
     90                // BROWSE ALL THE RECORDS 
     91                for (OIdentifiable id : target) { 
     92                        final ORecordInternal<?> record = (ORecordInternal<?>) id.getRecord(); 
     93 
     94                        if (record != null && record.getRecordType() != ODocument.RECORD_TYPE) 
     95                                // WRONG RECORD TYPE: JUMP IT 
     96                                continue; 
     97 
     98                        queryRecord.setRecord((ODocument) record); 
     99 
     100                        if (filter(queryRecord)) { 
     101                                resultCount++; 
     102                                resultListener.result(record.copy()); 
     103 
     104                                if (limit > -1 && resultCount == limit) 
     105                                        // BREAK THE EXECUTION 
     106                                        break; 
     107                        } 
     108                } 
     109 
    87110                return null; 
    88111        } 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/query/nativ/ONativeQuery.java

    r19299 r19635  
    2323@SuppressWarnings("serial") 
    2424public abstract class ONativeQuery<CTX extends OQueryContextNative> extends OQueryAbstract<ODocument> { 
    25         protected String        cluster; 
     25        protected String        className; 
     26        protected boolean       polymorphic     = true; 
    2627        protected CTX                   queryRecord; 
    2728 
     
    2930 
    3031        protected ONativeQuery(final String iCluster) { 
    31                 cluster = iCluster; 
     32                className = iCluster; 
    3233        } 
    3334 
     
    4041        } 
    4142 
     43        public boolean isPolymorphic() { 
     44                return polymorphic; 
     45        } 
     46 
     47        public void setPolymorphic(boolean polymorphic) { 
     48                this.polymorphic = polymorphic; 
     49        } 
     50 
    4251} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/record/ORecordAbstract.java

    r19299 r19635  
    172172 
    173173        public String toJSON() { 
    174                 return toJSON("rid,version,class,type,attribSameRow"); 
     174                return toJSON("rid,version,class,type,attribSameRow,alwaysFetchEmbedded,fetchPlan:*:0"); 
    175175        } 
    176176 
     
    354354                return (RET) copy(); 
    355355        } 
     356 
     357        protected void checkForLoading() { 
     358                if (_status == ORecordElement.STATUS.NOT_LOADED && ODatabaseRecordThreadLocal.INSTANCE.isDefined()) 
     359                        reload(null, true); 
     360        } 
    356361} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/record/ORecordSchemaAwareAbstract.java

    r19431 r19635  
    6767                checkForFields(); 
    6868 
    69                 if (_clazz != null) 
     69                if (_clazz != null) { 
     70                        if (_clazz.isStrictMode()) { 
     71                                // CHECK IF ALL FIELDS ARE DEFINED 
     72                                for (String f : fieldNames()) { 
     73                                        if (_clazz.getProperty(f) == null) 
     74                                                throw new OValidationException("Found additional field '" + f + "'. It cannot be added because the schema class '" 
     75                                                                + _clazz.getName() + "' is defined as STRICT"); 
     76                                } 
     77                        } 
     78 
    7079                        for (OProperty p : _clazz.properties()) { 
    7180                                validateField(this, p); 
    7281                        } 
     82                } 
    7383        } 
    7484 
     
    290300                } 
    291301        } 
    292  
    293         protected void checkForLoading() { 
    294                 if (_status == ORecordElement.STATUS.NOT_LOADED && ODatabaseRecordThreadLocal.INSTANCE.isDefined()) 
    295                         reload(null, true); 
    296         } 
    297302} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/record/impl/ODocument.java

    r19448 r19635  
    3434import com.orientechnologies.orient.core.db.record.ODetachable; 
    3535import com.orientechnologies.orient.core.db.record.ORecordElement; 
     36import com.orientechnologies.orient.core.db.record.ORecordLazyMultiValue; 
    3637import com.orientechnologies.orient.core.exception.ORecordNotFoundException; 
    3738import com.orientechnologies.orient.core.id.ORID; 
     
    8990 
    9091        /** 
    91          * Creates a new instance and binds to the specified database. New instances are not persistent until {@link #save()} is called. 
    92          *  
    93          * @param iDatabase 
    94          *          Database instance 
    95          */ 
     92         * Deprecated: use {@link #ODocument()} instead. ODocument instances always refer to the thread-local database and not anymore to 
     93         * the passed database as parameter. 
     94         */ 
     95        @Deprecated 
    9696        public ODocument(final ODatabaseRecord iDatabase) { 
    97                 setup(); 
    98         } 
    99  
     97                this(); 
     98        } 
     99 
     100        /** 
     101         * Deprecated: use {@link #ODocument(ORID)} instead. ODocument instances always refer to the thread-local database and not anymore 
     102         * to the passed database as parameter. 
     103         */ 
     104        @Deprecated 
    100105        public ODocument(final ODatabaseRecord iDatabase, final ORID iRID) { 
    101106                this(iRID); 
    102                 ODatabaseRecordThreadLocal.INSTANCE.set(iDatabase); 
    103107        } 
    104108 
     
    119123        } 
    120124 
     125        /** 
     126         * Deprecated: use {@link #ODocument(String, ORID)} instead. ODocument instances always refer to the thread-local database and not 
     127         * anymore to the passed database as parameter. 
     128         */ 
     129        @Deprecated 
    121130        public ODocument(final ODatabaseRecord iDatabase, final String iClassName, final ORID iRID) { 
    122131                this(iClassName, iRID); 
    123                 ODatabaseRecordThreadLocal.INSTANCE.set(iDatabase); 
    124132        } 
    125133 
     
    142150        } 
    143151 
     152        /** 
     153         * Deprecated: use {@link #ODocument(String)} instead. ODocument instances always refer to the thread-local database and not 
     154         * anymore to the passed database as parameter. 
     155         */ 
     156        @Deprecated 
    144157        public ODocument(final ODatabaseRecord iDatabase, final String iClassName) { 
    145                 ODatabaseRecordThreadLocal.INSTANCE.set(iDatabase); 
    146                 setClassName(iClassName); 
    147                 setup(); 
     158                this(iClassName); 
    148159        } 
    149160 
     
    270281        } 
    271282 
     283        /** 
     284         * Detaches all the connected records. If new records are linked to the document the detaching can't be completed and false will 
     285         * be returned. 
     286         *  
     287         * @return true if the record has been detached, otherwise false 
     288         */ 
    272289        public boolean detach() { 
    273290                boolean fullyDetached = true; 
     
    952969        public void setLazyLoad(final boolean iLazyLoad) { 
    953970                this._lazyLoad = iLazyLoad; 
     971 
     972                if (_fieldValues != null) { 
     973                        // PROPAGATE LAZINESS TO THE FIELDS 
     974                        for (Entry<String, Object> field : _fieldValues.entrySet()) { 
     975                                if (field.getValue() instanceof ORecordLazyMultiValue) 
     976                                        ((ORecordLazyMultiValue) field.getValue()).setAutoConvertToRecord(false); 
     977                        } 
     978                } 
    954979        } 
    955980 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/record/impl/ODocumentHelper.java

    r19431 r19635  
    636636                                                } 
    637637                                        } 
     638                                } else if (myFieldValue instanceof ODocument && otherFieldValue instanceof ODocument) { 
     639                                        return hasSameContentOf((ODocument) myFieldValue, (ODocument) otherFieldValue); 
    638640                                } else { 
     641 
    639642                                        if (!myFieldValue.equals(otherFieldValue)) 
    640643                                                return false; 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/record/impl/ORecordBytes.java

    r19431 r19635  
    1717 
    1818import java.io.ByteArrayInputStream; 
    19 import java.io.ByteArrayOutputStream; 
    2019import java.io.IOException; 
    2120import java.io.InputStream; 
     
    2827import com.orientechnologies.orient.core.id.ORecordId; 
    2928import com.orientechnologies.orient.core.record.ORecordAbstract; 
     29import com.orientechnologies.orient.core.serialization.OMemoryStream; 
    3030import com.orientechnologies.orient.core.serialization.serializer.record.ORecordSerializerFactory; 
    3131import com.orientechnologies.orient.core.serialization.serializer.record.ORecordSerializerRaw; 
     
    5050        } 
    5151 
    52         public ORecordBytes(final ODatabaseRecord iDatabase, byte[] iSource) { 
     52        public ORecordBytes(final ODatabaseRecord iDatabase, final byte[] iSource) { 
    5353                this(iSource); 
    5454                ODatabaseRecordThreadLocal.INSTANCE.set(iDatabase); 
     
    9898        } 
    9999 
    100         public void fromInputStream(final InputStream in) throws IOException { 
    101                 ByteArrayOutputStream out = new ByteArrayOutputStream(); 
     100        /** 
     101         * Reads the input stream in memory. This is less efficient than {@link #fromInputStream(InputStream, int)} because allocation is 
     102         * made multiple times. If you already know the input size use {@link #fromInputStream(InputStream, int)}. 
     103         *  
     104         * @param in 
     105         *          Input Stream, use buffered input stream wrapper to speed up reading 
     106         * @return Buffer read from the stream. It's also the internal buffer size in bytes 
     107         * @throws IOException 
     108         */ 
     109        public int fromInputStream(final InputStream in) throws IOException { 
     110                final OMemoryStream out = new OMemoryStream(); 
    102111                try { 
    103112                        while (in.available() > 0) { 
     
    110119                } 
    111120                _size = _source.length; 
     121                return _size; 
     122        } 
     123 
     124        /** 
     125         * Reads the input stream in memory specifying the maximum bytes to read. This is more efficient than 
     126         * {@link #fromInputStream(InputStream)} because allocation is made only once. If input stream contains less bytes than total size 
     127         * parameter, the rest of content will be empty (filled to 0) 
     128         *  
     129         * @param in 
     130         *          Input Stream, use buffered input stream wrapper to speed up reading 
     131         * @param iMaxSize 
     132         *          Maximin size to read 
     133         * @return Buffer read from the stream. It's also the internal buffer size in bytes 
     134         * @throws IOException 
     135         */ 
     136        public int fromInputStream(final InputStream in, final int iMaxSize) throws IOException { 
     137                final int bufferSize = Math.min(in.available(), iMaxSize); 
     138                _source = new byte[bufferSize]; 
     139                in.read(_source); 
     140                _size = bufferSize; 
     141                return _size; 
    112142        } 
    113143 
    114144        public void toOutputStream(final OutputStream out) throws IOException { 
     145                checkForLoading(); 
     146 
    115147                if (_source.length > 0) { 
    116148                        ByteArrayInputStream in = new ByteArrayInputStream(_source); 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/serialization/serializer/OStringSerializerHelper.java

    r19448 r19635  
    463463        } 
    464464 
     465        public static int getEmbedded(final String iText, final int iBeginPosition, int iEndPosition, final StringBuilder iEmbedded) { 
     466                final int openPos = iText.indexOf(EMBEDDED_BEGIN, iBeginPosition); 
     467                if (openPos == -1 || (iEndPosition > -1 && openPos > iEndPosition)) 
     468                        return iBeginPosition; 
     469 
     470                final StringBuilder buffer = new StringBuilder(); 
     471                parse(iText, buffer, openPos, iEndPosition, PARAMETER_EXT_SEPARATOR, true); 
     472                if (buffer.length() == 0) 
     473                        return iBeginPosition; 
     474 
     475                final String t = buffer.substring(1, buffer.length() - 1).trim(); 
     476                iEmbedded.append(t); 
     477                return iBeginPosition + buffer.length(); 
     478        } 
     479 
    465480        public static List<String> getParameters(final String iText) { 
    466481                final List<String> params = new ArrayList<String>(); 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/serialization/serializer/object/OObjectSerializerHelper.java

    r19431 r19635  
    4646import com.orientechnologies.orient.core.db.OUserObject2RecordHandler; 
    4747import com.orientechnologies.orient.core.db.object.ODatabaseObjectTx; 
    48 import com.orientechnologies.orient.core.db.object.OLazyObjectList; 
    4948import com.orientechnologies.orient.core.db.object.OLazyObjectMap; 
    50 import com.orientechnologies.orient.core.db.object.OLazyObjectSet; 
    5149import com.orientechnologies.orient.core.db.object.OObjectNotDetachedException; 
    52 import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    5350import com.orientechnologies.orient.core.db.record.ORecordElement; 
    5451import com.orientechnologies.orient.core.entity.OEntityManager; 
     
    5754import com.orientechnologies.orient.core.exception.OSerializationException; 
    5855import com.orientechnologies.orient.core.exception.OTransactionException; 
     56import com.orientechnologies.orient.core.fetch.OFetchContext; 
    5957import com.orientechnologies.orient.core.fetch.OFetchHelper; 
    6058import com.orientechnologies.orient.core.fetch.OFetchListener; 
     59import com.orientechnologies.orient.core.fetch.object.OObjectFetchContext; 
     60import com.orientechnologies.orient.core.fetch.object.OObjectFetchListener; 
    6161import com.orientechnologies.orient.core.id.ORID; 
    6262import com.orientechnologies.orient.core.id.ORecordId; 
     
    6464import com.orientechnologies.orient.core.metadata.schema.OProperty; 
    6565import com.orientechnologies.orient.core.metadata.schema.OType; 
    66 import com.orientechnologies.orient.core.record.ORecordInternal; 
    6766import com.orientechnologies.orient.core.record.impl.ODocument; 
    6867import com.orientechnologies.orient.core.serialization.serializer.record.OSerializationThreadLocal; 
    6968import com.orientechnologies.orient.core.tx.OTransactionOptimistic; 
    70 import com.orientechnologies.orient.core.type.tree.OMVRBTreeRIDSet; 
    7169 
    7270@SuppressWarnings("unchecked") 
     
    180178        } 
    181179 
    182         public static void setFieldValue(final Object iPojo, final String iProperty, Object iValue) { 
     180        public static void setFieldValue(final Object iPojo, final String iProperty, final Object iValue) { 
    183181                final Class<?> c = iPojo.getClass(); 
    184182                final String className = c.getName(); 
     
    292290                } 
    293291 
     292                final OFetchListener listener = new OObjectFetchListener(); 
     293                final OFetchContext context = new OObjectFetchContext(iFetchPlan, iLazyLoading, iEntityManager, iObj2RecHandler); 
    294294                // BIND LINKS FOLLOWING THE FETCHING PLAN 
    295                 final Map<String, Integer> fetchPlan = OFetchHelper.buildFetchPlan(iFetchPlan); 
    296                 OFetchHelper.fetch(iRecord, iPojo, fieldNames, fetchPlan, null, 0, -1, new OFetchListener() { 
    297                         /*** 
    298                          * Doesn't matter size. 
    299                          */ 
    300                         public int size() { 
    301                                 return 0; 
    302                         } 
    303  
    304                         public Object fetchLinked(final ODocument iRoot, final Object iUserObject, final String iFieldName, final Object iLinked) { 
    305                                 final Class<?> type; 
    306                                 if (iLinked != null && iLinked instanceof ODocument && (!"ORIDs".equals(((ODocument) iLinked).getClassName()))) 
    307                                         // GET TYPE BY DOCUMENT'S CLASS. THIS WORKS VERY WELL FOR SUB-TYPES 
    308                                         type = getFieldType((ODocument) iLinked, iEntityManager); 
    309                                 else 
    310                                         // DETERMINE TYPE BY REFLECTION 
    311                                         type = getFieldType(iUserObject, iFieldName); 
    312  
    313                                 if (type == null) 
    314                                         throw new OSerializationException( 
    315                                                         "Linked type of field '" 
    316                                                                         + iRoot.getClassName() 
    317                                                                         + "." 
    318                                                                         + iFieldName 
    319                                                                         + "' is unknown. Probably needs to be registered with <db>.getEntityManager().registerEntityClasses(<package>) or <db>.getEntityManager().registerEntityClass(<class>) or the package cannot be loaded correctly due to a classpath problem. In this case register the single classes one by one."); 
    320  
    321                                 Object fieldValue = null; 
    322                                 Class<?> fieldClass; 
    323                                 boolean propagate = false; 
    324  
    325                                 if (Set.class.isAssignableFrom(type)) { 
    326                                         final Collection<?> set; 
    327                                         if (iLinked instanceof Collection) 
    328                                                 set = (Collection<Object>) iLinked; 
    329                                         else 
    330                                                 set = new OMVRBTreeRIDSet().fromDocument((ODocument) iLinked); 
    331  
    332                                         final Set<Object> target; 
    333                                         if (iLazyLoading) 
    334                                                 target = new OLazyObjectSet<Object>(iRoot, (Collection<Object>) set).setFetchPlan(iFetchPlan); 
    335                                         else { 
    336                                                 target = new HashSet(); 
    337                                                 if (set != null && !set.isEmpty()) 
    338                                                         for (Object o : set) { 
    339                                                                 if (o instanceof OIdentifiable) 
    340                                                                         target.add(iObj2RecHandler.getUserObjectByRecord((ORecordInternal<?>) ((OIdentifiable) o).getRecord(), iFetchPlan)); 
    341                                                                 else 
    342                                                                         target.add(o); 
    343                                                         } 
    344                                         } 
    345                                         fieldValue = target; 
    346  
    347                                 } else if (Collection.class.isAssignableFrom(type)) { 
    348  
    349                                         final Collection<ODocument> list = (Collection<ODocument>) iLinked; 
    350                                         final List<Object> target; 
    351                                         if (iLazyLoading) 
    352                                                 target = new OLazyObjectList<Object>(iRoot, list).setFetchPlan(iFetchPlan); 
    353                                         else { 
    354                                                 target = new ArrayList(); 
    355                                                 if (list != null && !list.isEmpty()) 
    356                                                         for (Object o : list) { 
    357                                                                 if (o instanceof OIdentifiable) 
    358                                                                         target.add(iObj2RecHandler.getUserObjectByRecord((ORecordInternal<?>) ((OIdentifiable) o).getRecord(), iFetchPlan)); 
    359                                                                 else 
    360                                                                         target.add(o); 
    361                                                         } 
    362                                         } 
    363                                         fieldValue = target; 
    364  
    365                                 } else if (Map.class.isAssignableFrom(type)) { 
    366  
    367                                         final Map<Object, Object> map = (Map<Object, Object>) iLinked; 
    368                                         final Map<Object, Object> target; 
    369                                         if (iLazyLoading) 
    370                                                 target = new OLazyObjectMap<Object>(iRoot, map).setFetchPlan(iFetchPlan); 
    371                                         else { 
    372                                                 target = new HashMap(); 
    373                                                 if (map != null && !map.isEmpty()) 
    374                                                         for (Map.Entry<Object, Object> o : map.entrySet()) { 
    375                                                                 final Object k = o.getKey() instanceof OIdentifiable ? iObj2RecHandler.getUserObjectByRecord( 
    376                                                                                 (ORecordInternal<?>) ((OIdentifiable) o.getKey()).getRecord(), iFetchPlan) : o.getKey(); 
    377                                                                 final Object v = o.getValue() instanceof OIdentifiable ? iObj2RecHandler.getUserObjectByRecord( 
    378                                                                                 (ORecordInternal<?>) ((OIdentifiable) o.getValue()).getRecord(), iFetchPlan) : o.getValue(); 
    379                                                                 target.put(k, v); 
    380                                                         } 
    381                                         } 
    382                                         fieldValue = target; 
    383  
    384                                 } else if (type.isEnum()) { 
    385  
    386                                         String enumName = ((ODocument) iLinked).field(iFieldName); 
    387                                         Class<Enum> enumClass = (Class<Enum>) type; 
    388                                         fieldValue = Enum.valueOf(enumClass, enumName); 
    389  
    390                                 } else { 
    391  
    392                                         fieldClass = iEntityManager.getEntityClass(type.getSimpleName()); 
    393                                         if (fieldClass != null) { 
    394                                                 // RECOGNIZED TYPE 
    395                                                 propagate = !iObj2RecHandler.existsUserObjectByRID(((ODocument) iLinked).getIdentity()); 
    396  
    397                                                 fieldValue = iObj2RecHandler.getUserObjectByRecord((ODocument) iLinked, iFetchPlan); 
    398                                         } 
    399                                 } 
    400  
    401                                 setFieldValue(iUserObject, iFieldName, unserializeFieldValue(iPojo, iFieldName, fieldValue)); 
    402  
    403                                 return propagate ? fieldValue : null; 
    404                         } 
    405                 }); 
     295                OFetchHelper.fetch(iRecord, iPojo, OFetchHelper.buildFetchPlan(iFetchPlan), listener, context); 
    406296 
    407297                // CALL AFTER UNMARSHALLING 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/serialization/serializer/record/ORecordSerializerFactory.java

    r17050 r19635  
    11/* 
    2  * Copyright 1999-2010 Luca Garulli (l.garulli--at--orientechnologies.com) 
     2 * Copyright 1999-2012 Luca Garulli (l.garulli--at--orientechnologies.com) 
    33 * 
    44 * Licensed under the Apache License, Version 2.0 (the "License"); 
     
    2323import com.orientechnologies.orient.core.serialization.serializer.record.string.ORecordSerializerSchemaAware2CSV; 
    2424 
     25/** 
     26 * Factory of record serialized. 
     27 *  
     28 * @author Luca Garulli (l.garulli--at--orientechnologies.com) 
     29 *  
     30 */ 
    2531public class ORecordSerializerFactory { 
    2632        private static final ORecordSerializerFactory   instance                                = new ORecordSerializerFactory(); 
     
    3238                defaultRecordFormat = new ORecordSerializerRaw(); 
    3339 
    34                 implementations.put(ORecordSerializerSchemaAware2CSV.NAME, new ORecordSerializerSchemaAware2CSV()); 
    35                 implementations.put(ORecordSerializerJSON.NAME, new ORecordSerializerJSON()); 
    36                 implementations.put(ORecordSerializerRaw.NAME, defaultRecordFormat); 
     40                register(ORecordSerializerSchemaAware2CSV.NAME, new ORecordSerializerSchemaAware2CSV()); 
     41                register(ORecordSerializerJSON.NAME, new ORecordSerializerJSON()); 
     42                register(ORecordSerializerRaw.NAME, defaultRecordFormat); 
     43        } 
     44 
     45        /** 
     46         * Registers record serializer implementation. 
     47         *  
     48         * @param iName 
     49         *          Name to register, use JSON to overwrite default JSON serializer 
     50         * @param iInstance 
     51         *          Serializer implementation 
     52         */ 
     53        public void register(final String iName, final ORecordSerializer iInstance) { 
     54                implementations.put(iName, iInstance); 
    3755        } 
    3856 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/serialization/serializer/record/string/ORecordSerializerCSVAbstract.java

    r19431 r19635  
    8181                        final String value = iValue.startsWith("[") ? iValue.substring(1, iValue.length() - 1) : iValue; 
    8282 
    83                         return iType == OType.LINKLIST ? new ORecordLazyList(iSourceRecord).setStreamedContent(new StringBuilder(value)) 
     83                        return iType == OType.LINKLIST ? new ORecordLazyList((ODocument) iSourceRecord).setStreamedContent(new StringBuilder(value)) 
    8484                                        : new OMVRBTreeRIDSet(iSourceRecord).fromStream(new StringBuilder(iValue)); 
    8585                } 
     
    9393 
    9494                        @SuppressWarnings("rawtypes") 
    95                         final Map map = new ORecordLazyMap(iSourceRecord, ODocument.RECORD_TYPE); 
     95                        final Map map = new ORecordLazyMap((ODocument) iSourceRecord, ODocument.RECORD_TYPE); 
    9696 
    9797                        if (value.length() == 0) 
     
    528528                        } else { 
    529529                                if (linkedType == null) { 
    530                                         final char begin = value.charAt(0); 
     530                                        final char begin = item.charAt(0); 
    531531 
    532532                                        // AUTO-DETERMINE LINKED TYPE 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/serialization/serializer/record/string/ORecordSerializerDocument2Binary.java

    r19299 r19635  
    2424 
    2525import com.orientechnologies.common.log.OLogManager; 
    26 import com.orientechnologies.orient.core.db.document.ODatabaseDocument; 
    2726import com.orientechnologies.orient.core.db.record.ODatabaseRecord; 
    2827import com.orientechnologies.orient.core.exception.ODatabaseException; 
     
    4140        protected ORecordSchemaAware<?> newObject(ODatabaseRecord iDatabase, String iClassName) throws InstantiationException, 
    4241                        IllegalAccessException { 
    43                 return new ODocument(iDatabase); 
     42                return new ODocument(); 
    4443        } 
    4544 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/serialization/serializer/record/string/ORecordSerializerJSON.java

    r19431 r19635  
    2121import java.text.SimpleDateFormat; 
    2222import java.util.Collection; 
    23 import java.util.Date; 
    2423import java.util.HashMap; 
    2524import java.util.LinkedHashMap; 
     
    2827import java.util.Set; 
    2928 
    30 import com.orientechnologies.common.log.OLogManager; 
    3129import com.orientechnologies.common.parser.OStringParser; 
    3230import com.orientechnologies.orient.core.Orient; 
    3331import com.orientechnologies.orient.core.db.OUserObject2RecordHandler; 
    34 import com.orientechnologies.orient.core.db.record.ODatabaseRecord; 
    35 import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    3632import com.orientechnologies.orient.core.db.record.ORecordLazyList; 
    3733import com.orientechnologies.orient.core.db.record.OTrackedList; 
     
    3935import com.orientechnologies.orient.core.exception.OSerializationException; 
    4036import com.orientechnologies.orient.core.fetch.OFetchHelper; 
     37import com.orientechnologies.orient.core.fetch.json.OJSONFetchContext; 
     38import com.orientechnologies.orient.core.fetch.json.OJSONFetchListener; 
    4139import com.orientechnologies.orient.core.id.ORID; 
    4240import com.orientechnologies.orient.core.id.ORecordId; 
    43 import com.orientechnologies.orient.core.metadata.schema.OClass; 
    4441import com.orientechnologies.orient.core.metadata.schema.OProperty; 
    4542import com.orientechnologies.orient.core.metadata.schema.OType; 
     
    379376                        final StringWriter buffer = new StringWriter(); 
    380377                        final OJSONWriter json = new OJSONWriter(buffer, iFormat); 
    381                         final Map<ORID, Integer> parsedRecords = new HashMap<ORID, Integer>(); 
    382378 
    383379                        boolean includeVer; 
     
    386382                        boolean includeClazz; 
    387383                        boolean attribSameRow; 
     384                        boolean alwaysFetchEmbeddedDocuments; 
    388385                        int indentLevel; 
    389386                        String fetchPlan = null; 
     
    399396                                fetchPlan = ""; 
    400397                                keepTypes = true; 
     398                                alwaysFetchEmbeddedDocuments = true; 
    401399                        } else { 
    402400                                includeType = false; 
     
    405403                                includeClazz = false; 
    406404                                attribSameRow = false; 
     405                                alwaysFetchEmbeddedDocuments = false; 
    407406                                indentLevel = 0; 
    408407                                keepTypes = true; 
     
    426425                                        else if (f.startsWith("keepTypes")) 
    427426                                                keepTypes = true; 
     427                                        else if (f.startsWith("alwaysFetchEmbedded")) 
     428                                                alwaysFetchEmbeddedDocuments = true; 
    428429                        } 
    429430 
    430431                        json.beginObject(indentLevel); 
    431  
    432                         writeSignature(json, indentLevel, includeType, includeId, includeVer, includeClazz, attribSameRow, iRecord); 
     432                        OJSONFetchContext context = new OJSONFetchContext(json, includeType, includeId, includeVer, includeClazz, attribSameRow, 
     433                                        keepTypes, alwaysFetchEmbeddedDocuments); 
     434 
     435                        context.writeSignature(json, indentLevel, includeType, includeId, includeVer, includeClazz, attribSameRow, iRecord); 
    433436 
    434437                        if (iRecord instanceof ORecordSchemaAware<?>) { 
    435                                 // SCHEMA AWARE 
    436                                 final ORecordSchemaAware<?> record = (ORecordSchemaAware<?>) iRecord; 
    437                                 parsedRecords.put(iRecord.getIdentity(), 0); 
    438  
    439                                 Map<String, Integer> fetchPlanMap = null; 
    440                                 if (fetchPlan == null || fetchPlan.isEmpty()) 
    441                                         fetchPlan = "*:1"; 
    442                                 fetchPlanMap = OFetchHelper.buildFetchPlan(fetchPlan); 
    443                                 processRecordRidMap(record, fetchPlanMap, 0, -1, parsedRecords); 
    444                                 processRecord(json, indentLevel, includeType, includeId, includeVer, includeClazz, attribSameRow, record, fetchPlanMap, 
    445                                                 keepTypes, 0, -1, parsedRecords); 
     438 
     439                                OFetchHelper.fetch(iRecord, null, OFetchHelper.buildFetchPlan(fetchPlan), new OJSONFetchListener(), context); 
    446440                        } else if (iRecord instanceof ORecordStringable) { 
    447441 
     
    460454 
    461455                        json.endObject(indentLevel); 
    462                         parsedRecords.clear(); 
    463456 
    464457                        iOutput.append(buffer); 
     
    469462        } 
    470463 
    471         private void processRecord(final OJSONWriter json, int indentLevel, boolean includeType, boolean includeId, boolean includeVer, 
    472                         boolean includeClazz, boolean attribSameRow, final ORecordSchemaAware<?> record, Map<String, Integer> iFetchPlan, 
    473                         boolean keepTypes, final int iCurrentLevel, final int iMaxFetch, final Map<ORID, Integer> parsedRecords) throws IOException { 
    474                 if (iMaxFetch > -1 && iCurrentLevel >= iMaxFetch) 
    475                         // MAX FETCH SIZE REACHED: STOP TO FETCH AT ALL 
    476                         return; 
    477  
    478                 Object fieldValue; 
    479  
    480                 final StringBuilder types = new StringBuilder(); 
    481  
    482                 for (String fieldName : record.fieldNames()) { 
    483                         final int depthLevel = getDepthLevel(record, iFetchPlan, fieldName); 
    484                         if (depthLevel == 0) 
    485                                 continue; 
    486                         if (depthLevel > -1 && iCurrentLevel > depthLevel) { 
    487                                 // MAX DEPTH REACHED: STOP TO FETCH THIS FIELD 
    488                                 continue; 
    489                         } 
    490                         fieldValue = record.field(fieldName); 
    491                         if (fieldValue == null 
    492                                         || !(fieldValue instanceof OIdentifiable) 
    493                                         && (!(fieldValue instanceof Collection<?>) || ((Collection<?>) fieldValue).size() == 0 || !(((Collection<?>) fieldValue) 
    494                                                         .iterator().next() instanceof OIdentifiable)) 
    495                                         && (!(fieldValue instanceof Map<?, ?>) || ((Map<?, ?>) fieldValue).size() == 0 || !(((Map<?, ?>) fieldValue).values() 
    496                                                         .iterator().next() instanceof OIdentifiable))) { 
    497                                 if (keepTypes) { 
    498                                         if (fieldValue instanceof Long) 
    499                                                 appendType(types, fieldName, 'l'); 
    500                                         else if (fieldValue instanceof Float) 
    501                                                 appendType(types, fieldName, 'f'); 
    502                                         else if (fieldValue instanceof Short) 
    503                                                 appendType(types, fieldName, 's'); 
    504                                         else if (fieldValue instanceof Double) 
    505                                                 appendType(types, fieldName, 'd'); 
    506                                         else if (fieldValue instanceof Date) 
    507                                                 appendType(types, fieldName, 't'); 
    508                                         else if (fieldValue instanceof Byte) 
    509                                                 appendType(types, fieldName, 'b'); 
    510                                 } 
    511                                 json.writeAttribute(indentLevel + 1, true, fieldName, OJSONWriter.encode(fieldValue)); 
    512                         } else { 
    513                                 try { 
    514                                         fetch(record, iFetchPlan, fieldValue, fieldName, iCurrentLevel, iMaxFetch, json, indentLevel, includeType, includeId, 
    515                                                         includeVer, includeClazz, attribSameRow, keepTypes, parsedRecords, depthLevel); 
    516                                 } catch (Exception e) { 
    517                                         e.printStackTrace(); 
    518                                         OLogManager.instance().error(null, "Fetching error on record %s", e, record.getIdentity()); 
    519                                 } 
    520                         } 
    521                 } 
    522  
    523                 if (keepTypes && types.length() > 0) 
    524                         json.writeAttribute(indentLevel + 1, true, ATTRIBUTE_FIELD_TYPES, types.toString()); 
    525         } 
    526  
    527         private void appendType(final StringBuilder iBuffer, final String iFieldName, final char iType) { 
    528                 if (iBuffer.length() > 0) 
    529                         iBuffer.append(','); 
    530                 iBuffer.append(iFieldName); 
    531                 iBuffer.append('='); 
    532                 iBuffer.append(iType); 
    533         } 
    534  
    535         private void writeSignature(final OJSONWriter json, int indentLevel, boolean includeType, boolean includeId, boolean includeVer, 
    536                         boolean includeClazz, boolean attribSameRow, final ORecordInternal<?> record) throws IOException { 
    537                 boolean firstAttribute = true; 
    538                 if (includeType) { 
    539                         json.writeAttribute(firstAttribute ? indentLevel + 1 : 0, firstAttribute, ODocumentHelper.ATTRIBUTE_TYPE, 
    540                                         "" + (char) record.getRecordType()); 
    541                         if (attribSameRow) 
    542                                 firstAttribute = false; 
    543                 } 
    544                 if (includeId && record.getIdentity() != null && record.getIdentity().isValid()) { 
    545                         json.writeAttribute(!firstAttribute ? indentLevel + 1 : 0, firstAttribute, ODocumentHelper.ATTRIBUTE_RID, record 
    546                                         .getIdentity().toString()); 
    547                         if (attribSameRow) 
    548                                 firstAttribute = false; 
    549                 } 
    550                 if (includeVer) { 
    551                         json.writeAttribute(firstAttribute ? indentLevel + 1 : 0, firstAttribute, ODocumentHelper.ATTRIBUTE_VERSION, 
    552                                         record.getVersion()); 
    553                         if (attribSameRow) 
    554                                 firstAttribute = false; 
    555                 } 
    556                 if (includeClazz && record instanceof ORecordSchemaAware<?> && ((ORecordSchemaAware<?>) record).getClassName() != null) { 
    557                         json.writeAttribute(firstAttribute ? indentLevel + 1 : 0, firstAttribute, ODocumentHelper.ATTRIBUTE_CLASS, 
    558                                         ((ORecordSchemaAware<?>) record).getClassName()); 
    559                         if (attribSameRow) 
    560                                 firstAttribute = false; 
    561                 } 
    562         } 
    563  
    564         private void fetch(final ORecordSchemaAware<?> iRootRecord, final Map<String, Integer> iFetchPlan, final Object fieldValue, 
    565                         final String fieldName, final int iCurrentLevel, final int iMaxFetch, final OJSONWriter json, int indentLevel, 
    566                         boolean includeType, final boolean includeId, final boolean includeVer, final boolean includeClazz, 
    567                         final boolean attribSameRow, final boolean keepTypes, final Map<ORID, Integer> parsedRecords, final int depthLevel) 
    568                         throws IOException { 
    569  
    570                 if (depthLevel > -1 && iCurrentLevel > depthLevel) 
    571                         // MAX DEPTH REACHED: STOP TO FETCH THIS FIELD 
    572                         return; 
    573  
    574                 if (fieldValue == null) { 
    575                         json.writeAttribute(indentLevel + 1, true, fieldName, null); 
    576                 } else if (fieldValue instanceof ODocument) { 
    577                         fetchDocument(iFetchPlan, fieldValue, fieldName, iCurrentLevel, iMaxFetch, json, indentLevel, includeType, includeId, 
    578                                         includeVer, includeClazz, attribSameRow, keepTypes, parsedRecords); 
    579                 } else if (fieldValue instanceof Collection<?>) { 
    580                         fetchCollection(iFetchPlan, fieldValue, fieldName, iCurrentLevel, iMaxFetch, json, indentLevel, includeType, includeId, 
    581                                         includeVer, includeClazz, attribSameRow, keepTypes, parsedRecords); 
    582                 } else if (fieldValue.getClass().isArray()) { 
    583                         fetchArray(iFetchPlan, fieldValue, fieldName, iCurrentLevel, iMaxFetch, json, indentLevel, includeType, includeId, 
    584                                         includeVer, includeClazz, attribSameRow, keepTypes, parsedRecords); 
    585                 } else if (fieldValue instanceof Map<?, ?>) { 
    586                         fetchMap(iFetchPlan, fieldValue, fieldName, iCurrentLevel, iMaxFetch, json, indentLevel, includeType, includeId, includeVer, 
    587                                         includeClazz, attribSameRow, keepTypes, parsedRecords); 
    588                 } 
    589         } 
    590  
    591         @SuppressWarnings("unchecked") 
    592         private void fetchMap(Map<String, Integer> iFetchPlan, Object fieldValue, String fieldName, final int iCurrentLevel, 
    593                         final int iMaxFetch, final OJSONWriter json, final int indentLevel, final boolean includeType, final boolean includeId, 
    594                         final boolean includeVer, final boolean includeClazz, final boolean attribSameRow, final boolean keepTypes, 
    595                         final Map<ORID, Integer> parsedRecords) throws IOException { 
    596                 final Map<String, ODocument> linked = (Map<String, ODocument>) fieldValue; 
    597                 json.beginObject(indentLevel + 1, true, fieldName); 
    598                 for (String key : (linked).keySet()) { 
    599                         ODocument d = linked.get(key); 
    600                         // GO RECURSIVELY 
    601                         final Integer fieldDepthLevel = parsedRecords.get(d.getIdentity()); 
    602                         if (fieldDepthLevel != null && fieldDepthLevel.intValue() == iCurrentLevel) { 
    603                                 parsedRecords.remove(d.getIdentity()); 
    604                                 json.beginObject(indentLevel + 1, true, key); 
    605                                 writeSignature(json, indentLevel, includeType, includeId, includeVer, includeClazz, attribSameRow, d); 
    606                                 processRecord(json, indentLevel, includeType, includeId, includeVer, includeClazz, attribSameRow, d, iFetchPlan, keepTypes, 
    607                                                 iCurrentLevel + 1, iMaxFetch, parsedRecords); 
    608                                 json.endObject(indentLevel + 1, true); 
    609                         } else { 
    610                                 json.writeAttribute(indentLevel + 1, false, key, OJSONWriter.encode(d)); 
    611                         } 
    612                 } 
    613                 json.endObject(indentLevel + 1, true); 
    614         } 
    615  
    616         private void fetchArray(final Map<String, Integer> iFetchPlan, final Object fieldValue, final String fieldName, 
    617                         final int iCurrentLevel, final int iMaxFetch, final OJSONWriter json, final int indentLevel, final boolean includeType, 
    618                         final boolean includeId, final boolean includeVer, final boolean includeClazz, final boolean attribSameRow, 
    619                         final boolean keepTypes, final Map<ORID, Integer> parsedRecords) throws IOException { 
    620                 if (fieldValue instanceof ODocument[]) { 
    621                         final ODocument[] linked = (ODocument[]) fieldValue; 
    622                         json.beginCollection(indentLevel + 1, true, fieldName); 
    623                         for (ODocument d : linked) { 
    624                                 // GO RECURSIVELY 
    625                                 final Integer fieldDepthLevel = parsedRecords.get(d.getIdentity()); 
    626                                 if (fieldDepthLevel != null && fieldDepthLevel.intValue() == iCurrentLevel) { 
    627                                         parsedRecords.remove(d.getIdentity()); 
    628                                         json.beginObject(indentLevel + 1, true, null); 
    629                                         writeSignature(json, indentLevel, includeType, includeId, includeVer, includeClazz, attribSameRow, d); 
    630                                         processRecord(json, indentLevel, includeType, includeId, includeVer, includeClazz, attribSameRow, d, iFetchPlan, 
    631                                                         keepTypes, iCurrentLevel + 1, iMaxFetch, parsedRecords); 
    632                                         json.endObject(indentLevel + 1, true); 
    633                                 } else { 
    634                                         json.writeValue(indentLevel + 1, false, OJSONWriter.encode(d)); 
    635                                 } 
    636                         } 
    637                         json.endCollection(indentLevel + 1, false); 
    638                 } else { 
    639                         json.writeAttribute(indentLevel + 1, true, fieldName, null); 
    640                 } 
    641         } 
    642  
    643         @SuppressWarnings("unchecked") 
    644         private void fetchCollection(final Map<String, Integer> iFetchPlan, final Object fieldValue, final String fieldName, 
    645                         final int iCurrentLevel, final int iMaxFetch, final OJSONWriter json, final int indentLevel, final boolean includeType, 
    646                         final boolean includeId, final boolean includeVer, final boolean includeClazz, final boolean attribSameRow, 
    647                         final boolean keepTypes, final Map<ORID, Integer> parsedRecords) throws IOException { 
    648                 final Collection<ODocument> linked = (Collection<ODocument>) fieldValue; 
    649                 json.beginCollection(indentLevel + 1, true, fieldName); 
    650                 for (OIdentifiable d : linked) { 
    651                         // GO RECURSIVELY 
    652                         final Integer fieldDepthLevel = parsedRecords.get(d.getIdentity()); 
    653                         if (fieldDepthLevel != null && fieldDepthLevel.intValue() == iCurrentLevel) { 
    654                                 parsedRecords.remove(d.getIdentity()); 
    655                                 d = d.getRecord(); 
    656  
    657                                 if (!(d instanceof ODocument)) { 
    658                                         json.writeValue(indentLevel + 1, false, OJSONWriter.encode(d)); 
    659                                 } else { 
    660                                         json.beginObject(indentLevel + 1, true, null); 
    661                                         writeSignature(json, indentLevel, includeType, includeId, includeVer, includeClazz, attribSameRow, (ODocument) d); 
    662                                         processRecord(json, indentLevel, includeType, includeId, includeVer, includeClazz, attribSameRow, (ODocument) d, 
    663                                                         iFetchPlan, keepTypes, iCurrentLevel + 1, iMaxFetch, parsedRecords); 
    664                                         json.endObject(indentLevel + 1, true); 
    665                                 } 
    666                         } else { 
    667                                 json.writeValue(indentLevel + 1, false, OJSONWriter.encode(d)); 
    668                         } 
    669                 } 
    670                 json.endCollection(indentLevel + 1, false); 
    671         } 
    672  
    673         private void fetchDocument(Map<String, Integer> iFetchPlan, Object fieldValue, String fieldName, final int iCurrentLevel, 
    674                         final int iMaxFetch, OJSONWriter json, int indentLevel, boolean includeType, boolean includeId, boolean includeVer, 
    675                         boolean includeClazz, boolean attribSameRow, boolean keepTypes, final Map<ORID, Integer> parsedRecords) throws IOException { 
    676                 final Integer fieldDepthLevel = parsedRecords.get(((ODocument) fieldValue).getIdentity()); 
    677                 if (fieldDepthLevel != null && fieldDepthLevel.intValue() == iCurrentLevel) { 
    678                         parsedRecords.remove(((ODocument) fieldValue).getIdentity()); 
    679                         final ODocument linked = (ODocument) fieldValue; 
    680                         json.beginObject(indentLevel + 1, true, fieldName); 
    681                         writeSignature(json, indentLevel, includeType, includeId, includeVer, includeClazz, attribSameRow, linked); 
    682                         processRecord(json, indentLevel, includeType, includeId, includeVer, includeClazz, attribSameRow, linked, iFetchPlan, 
    683                                         keepTypes, iCurrentLevel + 1, iMaxFetch, parsedRecords); 
    684                         json.endObject(indentLevel + 1, true); 
    685                 } else { 
    686                         json.writeAttribute(indentLevel + 1, true, fieldName, OJSONWriter.encode(fieldValue)); 
    687                 } 
    688         } 
    689  
    690         private int getDepthLevel(final ORecordSchemaAware<?> record, final Map<String, Integer> iFetchPlan, final String iFieldName) { 
    691                 Integer depthLevel; 
    692  
    693                 if (iFetchPlan != null) { 
    694                         // GET THE FETCH PLAN FOR THE GENERIC FIELD IF SPECIFIED 
    695                         depthLevel = iFetchPlan.get(iFieldName); 
    696  
    697                         if (depthLevel == null) { 
    698                                 OClass cls = record.getSchemaClass(); 
    699                                 while (cls != null && depthLevel == null) { 
    700                                         depthLevel = iFetchPlan.get(cls.getName() + "." + iFieldName); 
    701  
    702                                         if (depthLevel == null) 
    703                                                 cls = cls.getSuperClass(); 
    704                                 } 
    705                                 if (depthLevel == null) { 
    706                                         final Integer anyLevel = iFetchPlan.get(OFetchHelper.ANY_FIELD); 
    707                                         depthLevel = anyLevel != null ? anyLevel : -1; 
    708                                 } 
    709                         } 
    710                 } else 
    711                         // INFINITE 
    712                         depthLevel = -1; 
    713  
    714                 return depthLevel.intValue(); 
    715         } 
    716  
    717464        private boolean hasTypeField(String[] fields) { 
    718465                for (int i = 0; i < fields.length; i = i + 2) { 
     
    724471        } 
    725472 
    726         private void processRecordRidMap(final ORecordSchemaAware<?> record, Map<String, Integer> iFetchPlan, final int iCurrentLevel, 
    727                         final int iMaxFetch, final Map<ORID, Integer> parsedRecords) throws IOException { 
    728                 if (iFetchPlan == null) 
    729                         return; 
    730  
    731                 if (iMaxFetch > -1 && iCurrentLevel >= iMaxFetch) 
    732                         // MAX FETCH SIZE REACHED: STOP TO FETCH AT ALL 
    733                         return; 
    734  
    735                 Object fieldValue; 
    736                 for (String fieldName : record.fieldNames()) { 
    737  
    738                         final int depthLevel = getDepthLevel(record, iFetchPlan, fieldName); 
    739                         if (depthLevel == 0) 
    740                                 // NO FETCH THIS FIELD PLEASE 
    741                                 continue; 
    742  
    743                         if (depthLevel > -1 && iCurrentLevel >= depthLevel - 1) 
    744                                 // MAX DEPTH REACHED: STOP TO FETCH THIS FIELD 
    745                                 continue; 
    746  
    747                         fieldValue = record.field(fieldName); 
    748                         if (fieldValue == null 
    749                                         || !(fieldValue instanceof OIdentifiable) 
    750                                         && (!(fieldValue instanceof Collection<?>) || ((Collection<?>) fieldValue).size() == 0 || !(((Collection<?>) fieldValue) 
    751                                                         .iterator().next() instanceof OIdentifiable)) 
    752                                         && (!(fieldValue instanceof Map<?, ?>) || ((Map<?, ?>) fieldValue).size() == 0 || !(((Map<?, ?>) fieldValue).values() 
    753                                                         .iterator().next() instanceof OIdentifiable))) { 
    754                                 continue; 
    755                         } else { 
    756                                 try { 
    757                                         fetchRidMap(record, iFetchPlan, fieldValue, fieldName, iCurrentLevel, iMaxFetch, parsedRecords); 
    758                                 } catch (Exception e) { 
    759                                         e.printStackTrace(); 
    760                                         OLogManager.instance().error(null, "Fetching error on record %s", e, record.getIdentity()); 
    761                                 } 
    762                         } 
    763                 } 
    764         } 
    765  
    766         private void fetchRidMap(final ORecordSchemaAware<?> iRootRecord, final Map<String, Integer> iFetchPlan, final Object fieldValue, 
    767                         final String fieldName, final int iCurrentLevel, final int iMaxFetch, final Map<ORID, Integer> parsedRecords) 
    768                         throws IOException { 
    769                 if (fieldValue == null) { 
    770                         return; 
    771                 } else if (fieldValue instanceof ODocument) { 
    772                         fetchDocumentRidMap(iFetchPlan, fieldValue, fieldName, iCurrentLevel, iMaxFetch, parsedRecords); 
    773                 } else if (fieldValue instanceof Collection<?>) { 
    774                         fetchCollectionRidMap(iRootRecord.getDatabase(), iFetchPlan, fieldValue, fieldName, iCurrentLevel, iMaxFetch, parsedRecords); 
    775                 } else if (fieldValue.getClass().isArray()) { 
    776                         fetchArrayRidMap(iFetchPlan, fieldValue, fieldName, iCurrentLevel, iMaxFetch, parsedRecords); 
    777                 } else if (fieldValue instanceof Map<?, ?>) { 
    778                         fetchMapRidMap(iFetchPlan, fieldValue, fieldName, iCurrentLevel, iMaxFetch, parsedRecords); 
    779                 } 
    780         } 
    781  
    782         private void fetchDocumentRidMap(Map<String, Integer> iFetchPlan, Object fieldValue, String fieldName, final int iCurrentLevel, 
    783                         final int iMaxFetch, final Map<ORID, Integer> parsedRecords) throws IOException { 
    784                 updateRidMap(iFetchPlan, (ODocument) fieldValue, iCurrentLevel, iMaxFetch, parsedRecords); 
    785         } 
    786  
    787         @SuppressWarnings("unchecked") 
    788         private void fetchCollectionRidMap(final ODatabaseRecord iDatabase, final Map<String, Integer> iFetchPlan, 
    789                         final Object fieldValue, final String fieldName, final int iCurrentLevel, final int iMaxFetch, 
    790                         final Map<ORID, Integer> parsedRecords) throws IOException { 
    791                 final Collection<ODocument> linked = (Collection<ODocument>) fieldValue; 
    792                 for (OIdentifiable d : linked) { 
    793                         // GO RECURSIVELY 
    794                         if (d instanceof ORecordId) 
    795                                 d = iDatabase.load((ORecordId) d); 
    796  
    797                         updateRidMap(iFetchPlan, (ODocument) d, iCurrentLevel, iMaxFetch, parsedRecords); 
    798                 } 
    799         } 
    800  
    801         private void fetchArrayRidMap(final Map<String, Integer> iFetchPlan, final Object fieldValue, final String fieldName, 
    802                         final int iCurrentLevel, final int iMaxFetch, final Map<ORID, Integer> parsedRecords) throws IOException { 
    803                 if (fieldValue instanceof ODocument[]) { 
    804                         final ODocument[] linked = (ODocument[]) fieldValue; 
    805                         for (ODocument d : linked) 
    806                                 // GO RECURSIVELY 
    807                                 updateRidMap(iFetchPlan, (ODocument) d, iCurrentLevel, iMaxFetch, parsedRecords); 
    808                 } 
    809         } 
    810  
    811         @SuppressWarnings("unchecked") 
    812         private void fetchMapRidMap(Map<String, Integer> iFetchPlan, Object fieldValue, String fieldName, final int iCurrentLevel, 
    813                         final int iMaxFetch, final Map<ORID, Integer> parsedRecords) throws IOException { 
    814                 final Map<String, ODocument> linked = (Map<String, ODocument>) fieldValue; 
    815                 for (ODocument d : (linked).values()) 
    816                         // GO RECURSIVELY 
    817                         updateRidMap(iFetchPlan, (ODocument) d, iCurrentLevel, iMaxFetch, parsedRecords); 
    818         } 
    819  
    820         private void updateRidMap(final Map<String, Integer> iFetchPlan, final ODocument fieldValue, final int iCurrentLevel, 
    821                         final int iMaxFetch, final Map<ORID, Integer> parsedRecords) throws IOException { 
    822                 Integer fetchedLevel = parsedRecords.get(fieldValue.getIdentity()); 
    823                 if (fetchedLevel == null) { 
    824                         parsedRecords.put(fieldValue.getIdentity(), iCurrentLevel); 
    825                         processRecordRidMap(fieldValue, iFetchPlan, iCurrentLevel + 1, iMaxFetch, parsedRecords); 
    826                 } else if (fetchedLevel > iCurrentLevel) { 
    827                         parsedRecords.put(fieldValue.getIdentity(), iCurrentLevel); 
    828                         processRecordRidMap((ODocument) fieldValue, iFetchPlan, iCurrentLevel + 1, iMaxFetch, parsedRecords); 
    829                 } 
    830         } 
    831  
    832473        @Override 
    833474        public String toString() { 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/serialization/serializer/record/string/ORecordSerializerSchemaAware2CSV.java

    r19431 r19635  
    1616package com.orientechnologies.orient.core.serialization.serializer.record.string; 
    1717 
     18import java.math.BigDecimal; 
     19import java.math.BigInteger; 
    1820import java.util.Collection; 
    1921import java.util.Date; 
     
    137139                                        else if (fieldValue instanceof String) 
    138140                                                type = OType.STRING; 
    139                                         else if (fieldValue instanceof Integer) 
     141                                        else if (fieldValue instanceof Integer || fieldValue instanceof BigInteger) 
    140142                                                type = OType.INTEGER; 
    141143                                        else if (fieldValue instanceof Long) 
     
    149151                                        else if (fieldValue instanceof Double) 
    150152                                                type = OType.DOUBLE; 
     153                                        else if (fieldValue instanceof BigDecimal) 
     154                                                type = OType.DECIMAL; 
    151155                                } 
    152156 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/serialization/serializer/record/string/ORecordSerializerStringAbstract.java

    r19299 r19635  
    1717 
    1818import java.io.Serializable; 
     19import java.math.BigDecimal; 
    1920import java.util.Calendar; 
    2021import java.util.Date; 
     
    9394                switch (iType) { 
    9495                case STRING: 
    95                         if (iValue instanceof String) { 
    96                                 final String s = OStringSerializerHelper.getStringContent(iValue); 
    97                                 return OStringSerializerHelper.decode(s); 
    98                         } 
    99                         return iValue.toString(); 
    100  
    10196                case INTEGER: 
    102                         if (iValue instanceof Integer) 
    103                                 return iValue; 
    104                         return new Integer(iValue.toString()); 
    105  
    10697                case BOOLEAN: 
    107                         if (iValue instanceof Boolean) 
    108                                 return iValue; 
    109                         return new Boolean(iValue.toString()); 
    110  
    11198                case FLOAT: 
    112                         if (iValue instanceof Float) 
    113                                 return iValue; 
    114                         return convertValue((String) iValue, iType); 
    115  
     99                case DECIMAL: 
    116100                case LONG: 
    117                         if (iValue instanceof Long) 
    118                                 return iValue; 
    119                         return convertValue((String) iValue, iType); 
    120  
    121101                case DOUBLE: 
    122                         if (iValue instanceof Double) 
    123                                 return iValue; 
    124                         return convertValue((String) iValue, iType); 
    125  
    126102                case SHORT: 
    127                         if (iValue instanceof Short) 
    128                                 return iValue; 
    129                         return convertValue((String) iValue, iType); 
    130  
    131103                case BYTE: 
    132                         if (iValue instanceof Byte) 
    133                                 return iValue; 
    134                         return convertValue((String) iValue, iType); 
    135  
    136104                case BINARY: 
    137                         return OStringSerializerHelper.getBinaryContent(iValue); 
    138  
    139105                case DATE: 
    140106                case DATETIME: 
    141                         if (iValue instanceof Date) 
    142                                 return iValue; 
    143                         return convertValue((String) iValue, iType); 
    144  
    145107                case LINK: 
    146                         if (iValue instanceof ORID) 
    147                                 return iValue.toString(); 
    148                         else if (iValue instanceof String) 
    149                                 return new ORecordId((String) iValue); 
    150                         else 
    151                                 return ((ORecord<?>) iValue).getIdentity().toString(); 
     108      return simpleValueFromStream( iValue, iType ); 
    152109 
    153110                case EMBEDDED: 
     
    211168                        simpleValueToStream(iBuffer, iType, iValue); 
    212169                        OProfiler.getInstance().stopChrono("serializer.rec.str.float2string", timer); 
     170                        break; 
     171 
     172                case DECIMAL: 
     173                        simpleValueToStream(iBuffer, iType, iValue); 
     174                        OProfiler.getInstance().stopChrono("serializer.rec.str.decimal2string", timer); 
    213175                        break; 
    214176 
     
    344306                                                } else if (c == 'f') 
    345307                                                        return OType.FLOAT; 
     308                                                else if (c == 'c') 
     309                                                        return OType.DECIMAL; 
    346310                                                else if (c == 'l') 
    347311                                                        return OType.LONG; 
     
    427391                                                if (c == 'f') 
    428392                                                        return new Float(v); 
     393                                                else if (c == 'c') 
     394                                                        return new BigDecimal(v); 
    429395                                                else if (c == 'l') 
    430396                                                        return new Long(v); 
     
    448414        } 
    449415 
     416  public static Object simpleValueFromStream(final Object iValue,  final OType iType) { 
     417    switch (iType) { 
     418      case STRING: 
     419        if (iValue instanceof String) { 
     420          final String s = OStringSerializerHelper.getStringContent(iValue); 
     421          return OStringSerializerHelper.decode(s); 
     422        } 
     423        return iValue.toString(); 
     424 
     425      case INTEGER: 
     426        if (iValue instanceof Integer) 
     427          return iValue; 
     428        return new Integer(iValue.toString()); 
     429 
     430      case BOOLEAN: 
     431        if (iValue instanceof Boolean) 
     432          return iValue; 
     433        return new Boolean(iValue.toString()); 
     434 
     435      case FLOAT: 
     436        if (iValue instanceof Float) 
     437          return iValue; 
     438        return convertValue((String) iValue, iType); 
     439 
     440      case DECIMAL: 
     441        if (iValue instanceof BigDecimal) 
     442          return iValue; 
     443        return convertValue((String) iValue, iType); 
     444 
     445      case LONG: 
     446        if (iValue instanceof Long) 
     447          return iValue; 
     448        return convertValue((String) iValue, iType); 
     449 
     450      case DOUBLE: 
     451        if (iValue instanceof Double) 
     452          return iValue; 
     453        return convertValue((String) iValue, iType); 
     454 
     455      case SHORT: 
     456        if (iValue instanceof Short) 
     457          return iValue; 
     458        return convertValue((String) iValue, iType); 
     459 
     460      case BYTE: 
     461        if (iValue instanceof Byte) 
     462          return iValue; 
     463        return convertValue((String) iValue, iType); 
     464 
     465      case BINARY: 
     466        return OStringSerializerHelper.getBinaryContent(iValue); 
     467 
     468      case DATE: 
     469      case DATETIME: 
     470        if (iValue instanceof Date) 
     471          return iValue; 
     472        return convertValue((String) iValue, iType); 
     473 
     474      case LINK: 
     475        if (iValue instanceof ORID) 
     476          return iValue.toString(); 
     477        else if (iValue instanceof String) 
     478          return new ORecordId((String) iValue); 
     479        else 
     480          return ((ORecord<?>) iValue).getIdentity().toString(); 
     481    } 
     482 
     483    throw new IllegalArgumentException("Type " + iType + " is not simple type."); 
     484  } 
     485 
    450486        public static void simpleValueToStream(final StringBuilder iBuffer, final OType iType, final Object iValue) { 
    451487                if (iValue == null || iType == null) 
     
    469505                        iBuffer.append(String.valueOf(iValue)); 
    470506                        iBuffer.append('f'); 
     507                        break; 
     508 
     509                case DECIMAL: 
     510                        iBuffer.append(String.valueOf(iValue)); 
     511                        iBuffer.append('c'); 
    471512                        break; 
    472513 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/serialization/serializer/stream/OCompositeKeySerializer.java

    r19431 r19635  
    44 
    55import com.orientechnologies.common.collection.OCompositeKey; 
     6import com.orientechnologies.orient.core.metadata.schema.OType; 
     7import com.orientechnologies.orient.core.serialization.OBinaryProtocol; 
    68import com.orientechnologies.orient.core.serialization.OMemoryInputStream; 
    79import com.orientechnologies.orient.core.serialization.OMemoryStream; 
     10import com.orientechnologies.orient.core.serialization.serializer.record.string.ORecordSerializerStringAbstract; 
    811 
    912/** 
     
    1922 
    2023                final OMemoryStream outputStream = new OMemoryStream(); 
    21                 outputStream.set(compositeKey.getKeys().size()); 
     24                outputStream.set( compositeKey.getKeys().size() ); 
     25     
    2226                for (final Comparable<?> comparable : compositeKey.getKeys()) { 
    23                         outputStream.set(OStreamSerializerLiteral.INSTANCE.toStream(comparable)); 
     27      final StringBuilder builder = new StringBuilder(  ); 
     28      final OType type =  OType.getTypeByClass( comparable.getClass() ); 
     29      builder.append( type.toString()); 
     30      builder.append( "," ); 
     31      ORecordSerializerStringAbstract.fieldTypeToString(builder, type, comparable); 
     32       
     33                        outputStream.set( OBinaryProtocol.string2bytes( builder.toString() )); 
    2434                } 
    2535 
     
    3343                final int keysSize = inputStream.getAsInteger(); 
    3444                for (int i = 0; i < keysSize; i++) { 
    35                         compositeKey.addKey((Comparable<?>) OStreamSerializerLiteral.INSTANCE.fromStream(inputStream.getAsByteArray())); 
     45      final byte[] keyBytes = inputStream.getAsByteArray(); 
     46      final String keyString = OBinaryProtocol.bytes2string(keyBytes); 
     47      final int typeSeparatorPos = keyString.indexOf( ',' );  
     48      final OType type = OType.valueOf( keyString.substring( 0, typeSeparatorPos ) ); 
     49      compositeKey.addKey((Comparable)ORecordSerializerStringAbstract.simpleValueFromStream( keyString.substring( typeSeparatorPos + 1 ), type )); 
    3650                } 
    3751                return compositeKey; 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLAbstract.java

    r19299 r19635  
    4343                return (OCommandExecutorSQLAbstract) super.init(iText); 
    4444        } 
     45 
     46        public abstract String getSyntax(); 
    4547} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLAlterClass.java

    r19299 r19635  
    3636 */ 
    3737@SuppressWarnings("unchecked") 
    38 public class OCommandExecutorSQLAlterClass extends OCommandExecutorSQLPermissionAbstract { 
     38public class OCommandExecutorSQLAlterClass extends OCommandExecutorSQLAbstract { 
    3939        public static final String      KEYWORD_ALTER   = "ALTER"; 
    4040        public static final String      KEYWORD_CLASS   = "CLASS"; 
     
    127127                return true; 
    128128        } 
     129 
     130        public String getSyntax() { 
     131                return "ALTER CLASS <class> <attribute-name> <attribute-value>"; 
     132        } 
    129133} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLAlterCluster.java

    r19299 r19635  
    3838 */ 
    3939@SuppressWarnings("unchecked") 
    40 public class OCommandExecutorSQLAlterCluster extends OCommandExecutorSQLPermissionAbstract { 
     40public class OCommandExecutorSQLAlterCluster extends OCommandExecutorSQLAbstract { 
    4141        public static final String      KEYWORD_ALTER           = "ALTER"; 
    4242        public static final String      KEYWORD_CLUSTER = "CLUSTER"; 
     
    5858                int pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    5959                if (pos == -1 || !word.toString().equals(KEYWORD_ALTER)) 
    60                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_ALTER + " not found", text, oldPos); 
     60                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_ALTER + " not found. Use " + getSyntax(), text, oldPos); 
    6161 
    6262                oldPos = pos; 
    6363                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    6464                if (pos == -1 || !word.toString().equals(KEYWORD_CLUSTER)) 
    65                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_CLUSTER + " not found", text, oldPos); 
     65                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_CLUSTER + " not found. Use " + getSyntax(), text, oldPos); 
    6666 
    6767                oldPos = pos; 
    6868                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, false); 
    6969                if (pos == -1) 
    70                         throw new OCommandSQLParsingException("Expected <cluster-name>", text, oldPos); 
     70                        throw new OCommandSQLParsingException("Expected <cluster-name>. Use " + getSyntax(), text, oldPos); 
    7171 
    7272                clusterName = word.toString(); 
     
    8080                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    8181                if (pos == -1) 
    82                         throw new OCommandSQLParsingException("Missing cluster attribute to change", text, oldPos); 
     82                        throw new OCommandSQLParsingException("Missing cluster attribute to change. Use " + getSyntax(), text, oldPos); 
    8383 
    8484                final String attributeAsString = word.toString(); 
     
    9494 
    9595                if (value.length() == 0) 
    96                         throw new OCommandSQLParsingException("Missing property value to change for attribute '" + attribute + "'", text, oldPos); 
     96                        throw new OCommandSQLParsingException("Missing property value to change for attribute '" + attribute + "'. Use " 
     97                                        + getSyntax(), text, oldPos); 
    9798 
    9899                if (value.equalsIgnoreCase("null")) 
     
    136137                        return database.getStorage().getClusterById(database.getStorage().getClusterIdByName(clusterName)); 
    137138                } 
     139        } 
    138140 
     141        public String getSyntax() { 
     142                return "ALTER CLUSTER <cluster-name>|<cluster-id> <attribute-name> <attribute-value>"; 
    139143        } 
    140144} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLAlterDatabase.java

    r19299 r19635  
    3636 */ 
    3737@SuppressWarnings("unchecked") 
    38 public class OCommandExecutorSQLAlterDatabase extends OCommandExecutorSQLPermissionAbstract { 
     38public class OCommandExecutorSQLAlterDatabase extends OCommandExecutorSQLAbstract { 
    3939        public static final String              KEYWORD_ALTER                   = "ALTER"; 
    4040        public static final String              KEYWORD_DATABASE        = "DATABASE"; 
     
    5454                int pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    5555                if (pos == -1 || !word.toString().equals(KEYWORD_ALTER)) 
    56                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_ALTER + " not found", text, oldPos); 
     56                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_ALTER + " not found. Use " + getSyntax(), text, oldPos); 
    5757 
    5858                oldPos = pos; 
    5959                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    6060                if (pos == -1 || !word.toString().equals(KEYWORD_DATABASE)) 
    61                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_DATABASE + " not found", text, oldPos); 
     61                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_DATABASE + " not found. Use " + getSyntax(), text, oldPos); 
    6262 
    6363                oldPos = pos; 
    6464                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    6565                if (pos == -1) 
    66                         throw new OCommandSQLParsingException("Missed the database's attribute to change", text, oldPos); 
     66                        throw new OCommandSQLParsingException("Missed the database's attribute to change. Use " + getSyntax(), text, oldPos); 
    6767 
    6868                final String attributeAsString = word.toString(); 
     
    7878 
    7979                if (value.length() == 0) 
    80                         throw new OCommandSQLParsingException("Missed the database's value to change for attribute '" + attribute + "'", text, oldPos); 
     80                        throw new OCommandSQLParsingException("Missed the database's value to change for attribute '" + attribute + "'. Use " 
     81                                        + getSyntax(), text, oldPos); 
    8182 
    8283                if (value.equalsIgnoreCase("null")) 
     
    99100                return null; 
    100101        } 
     102 
     103        public String getSyntax() { 
     104                return "ALTER DATABASE <attribute-name> <attribute-value>"; 
     105        } 
    101106} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLAlterProperty.java

    r19299 r19635  
    3636 */ 
    3737@SuppressWarnings("unchecked") 
    38 public class OCommandExecutorSQLAlterProperty extends OCommandExecutorSQLPermissionAbstract { 
     38public class OCommandExecutorSQLAlterProperty extends OCommandExecutorSQLAbstract { 
    3939        public static final String      KEYWORD_ALTER                   = "ALTER"; 
    4040        public static final String      KEYWORD_PROPERTY        = "PROPERTY"; 
     
    5555                int pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    5656                if (pos == -1 || !word.toString().equals(KEYWORD_ALTER)) 
    57                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_ALTER + " not found", text, oldPos); 
     57                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_ALTER + " not found. Use " + getSyntax(), text, oldPos); 
    5858 
    5959                oldPos = pos; 
    6060                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    6161                if (pos == -1 || !word.toString().equals(KEYWORD_PROPERTY)) 
    62                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_PROPERTY + " not found", text, oldPos); 
     62                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_PROPERTY + " not found. Use " + getSyntax(), text, oldPos); 
    6363 
    6464                oldPos = pos; 
    6565                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, false); 
    6666                if (pos == -1) 
    67                         throw new OCommandSQLParsingException("Expected <class>.<property>", text, oldPos); 
     67                        throw new OCommandSQLParsingException("Expected <class>.<property>. Use " + getSyntax(), text, oldPos); 
    6868 
    6969                String[] parts = word.toString().split("\\."); 
    7070                if (parts.length != 2) 
    71                         throw new OCommandSQLParsingException("Expected <class>.<property>", text, oldPos); 
     71                        throw new OCommandSQLParsingException("Expected <class>.<property>. Use " + getSyntax(), text, oldPos); 
    7272 
    7373                className = parts[0]; 
     
    7979                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    8080                if (pos == -1) 
    81                         throw new OCommandSQLParsingException("Missing property attribute to change", text, oldPos); 
     81                        throw new OCommandSQLParsingException("Missing property attribute to change. Use " + getSyntax(), text, oldPos); 
    8282 
    8383                final String attributeAsString = word.toString(); 
     
    9393 
    9494                if (value.length() == 0) 
    95                         throw new OCommandSQLParsingException("Missing property value to change for attribute '" + attribute + "'", text, oldPos); 
     95                        throw new OCommandSQLParsingException("Missing property value to change for attribute '" + attribute + "'. Use " 
     96                                        + getSyntax(), text, oldPos); 
    9697 
    9798                if (value.equalsIgnoreCase("null")) 
     
    119120                return null; 
    120121        } 
     122 
     123        public String getSyntax() { 
     124                return "ALTER PROPERTY <class>.<property> <attribute-name> <attribute-value>"; 
     125        } 
    121126} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLCreateClass.java

    r19299 r19635  
    3434 */ 
    3535@SuppressWarnings("unchecked") 
    36 public class OCommandExecutorSQLCreateClass extends OCommandExecutorSQLPermissionAbstract { 
     36public class OCommandExecutorSQLCreateClass extends OCommandExecutorSQLAbstract { 
    3737        public static final String      KEYWORD_CREATE  = "CREATE"; 
    3838        public static final String      KEYWORD_CLASS           = "CLASS"; 
     
    5555                int pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    5656                if (pos == -1 || !word.toString().equals(KEYWORD_CREATE)) 
    57                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_CREATE + " not found", text, oldPos); 
     57                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_CREATE + " not found. Use " + getSyntax(), text, oldPos); 
    5858 
    5959                oldPos = pos; 
    6060                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    6161                if (pos == -1 || !word.toString().equals(KEYWORD_CLASS)) 
    62                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_CLASS + " not found", text, oldPos); 
     62                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_CLASS + " not found. Use " + getSyntax(), text, oldPos); 
    6363 
    6464                oldPos = pos; 
     
    8080                                if (pos == -1) 
    8181                                        throw new OCommandSQLParsingException("Syntax error after EXTENDS for class " + className 
    82                                                         + ". Expected the super-class name", text, oldPos); 
     82                                                        + ". Expected the super-class name. Use " + getSyntax(), text, oldPos); 
    8383 
    8484                                if (!database.getMetadata().getSchema().existsClass(word.toString())) 
     
    9191                                if (pos == -1) 
    9292                                        throw new OCommandSQLParsingException("Syntax error after CLUSTER for class " + className 
    93                                                         + ". Expected the cluster id or name", text, oldPos); 
     93                                                        + ". Expected the cluster id or name. Use " + getSyntax(), text, oldPos); 
    9494 
    9595                                final String[] clusterIdsAsStrings = word.toString().split(","); 
     
    139139                return database.getMetadata().getSchema().getClasses().size(); 
    140140        } 
     141 
     142        @Override 
     143        public String getSyntax() { 
     144                return "CREATE CLASS <class> [EXTENDS <super-class>] [CLUSTER <clusterId>*]"; 
     145        } 
    141146} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLCreateIndex.java

    r19431 r19635  
    4545 */ 
    4646@SuppressWarnings("unchecked") 
    47 public class OCommandExecutorSQLCreateIndex extends OCommandExecutorSQLPermissionAbstract { 
     47public class OCommandExecutorSQLCreateIndex extends OCommandExecutorSQLAbstract { 
    4848        public static final String      KEYWORD_CREATE  = "CREATE"; 
    4949        public static final String      KEYWORD_INDEX           = "INDEX"; 
     
    6666                int pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    6767                if (pos == -1 || !word.toString().equals(KEYWORD_CREATE)) 
    68                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_CREATE + " not found", text, oldPos); 
     68                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_CREATE + " not found. Use " + getSyntax(), text, oldPos); 
    6969 
    7070                oldPos = pos; 
    7171                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    7272                if (pos == -1 || !word.toString().equals(KEYWORD_INDEX)) 
    73                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_INDEX + " not found", text, oldPos); 
     73                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_INDEX + " not found. Use " + getSyntax(), text, oldPos); 
    7474 
    7575                oldPos = pos; 
    7676                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, false); 
    7777                if (pos == -1) 
    78                         throw new OCommandSQLParsingException("Expected index name", text, oldPos); 
     78                        throw new OCommandSQLParsingException("Expected index name. Use " + getSyntax(), text, oldPos); 
    7979 
    8080                indexName = word.toString(); 
     
    8484                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    8585                if (pos == -1) 
    86                         throw new OCommandSQLParsingException("Index type requested", text, oldPos + 1); 
     86                        throw new OCommandSQLParsingException("Index type requested. Use " + getSyntax(), text, oldPos + 1); 
    8787 
    8888                if (word.toString().equals(KEYWORD_ON)) { 
    8989                        if (indexName.contains(".")) { 
    90                                 throw new OCommandSQLParsingException("Index name cannot contain '.' character", text, namePos); 
     90                                throw new OCommandSQLParsingException("Index name cannot contain '.' character. Use " + getSyntax(), text, namePos); 
    9191                        } 
    9292 
     
    9494                        pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    9595                        if (pos == -1) 
    96                                 throw new OCommandSQLParsingException("Expected class name", text, oldPos); 
     96                                throw new OCommandSQLParsingException("Expected class name. Use " + getSyntax(), text, oldPos); 
    9797                        oldPos = pos; 
    9898                        oClass = findClass(word.toString()); 
     
    103103                        pos = textUpperCase.indexOf(")"); 
    104104                        if (pos == -1) { 
    105                                 throw new OCommandSQLParsingException("No right bracket found", text, oldPos); 
     105                                throw new OCommandSQLParsingException("No right bracket found. Use " + getSyntax(), text, oldPos); 
    106106                        } 
    107107 
     
    111111                        final List<OType> typeList = new ArrayList<OType>(); 
    112112                        for (String propToIndex : props.trim().split("\\s*,\\s*")) { 
    113         checkMapIndexSpecifier( propToIndex, text, oldPos ); 
    114         final String propName = propToIndex.split( "\\s+" )[0]; 
     113                                checkMapIndexSpecifier(propToIndex, text, oldPos); 
     114                                final String propName = propToIndex.split("\\s+")[0]; 
    115115 
    116116                                final OProperty property = oClass.getProperty(propName); 
     
    129129                        pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    130130                        if (pos == -1) 
    131                                 throw new OCommandSQLParsingException("Index type requested", text, oldPos + 1); 
     131                                throw new OCommandSQLParsingException("Index type requested. Use " + getSyntax(), text, oldPos + 1); 
    132132 
    133133                        keyTypes = new OType[propList.size()]; 
     
    208208        } 
    209209 
    210   private void checkMapIndexSpecifier(final String fieldName, final String text, final int pos) { 
    211     String[] fieldNameParts = fieldName.split( "\\s+" ); 
    212     if(fieldNameParts.length == 1) 
    213       return; 
    214  
    215     if(fieldNameParts.length == 3) { 
    216       if("by".equals(fieldNameParts[1].toLowerCase())) { 
    217         try{ 
    218           OPropertyMapIndexDefinition.INDEX_BY.valueOf( fieldNameParts[2].toUpperCase() ); 
    219         } catch( IllegalArgumentException iae ) { 
    220           throw new OCommandSQLParsingException( "Illegal field name format, should be '<property> [by key|value]' but was '" + fieldName + "'", text, pos); 
    221         } 
    222         return; 
    223       } 
    224       throw new OCommandSQLParsingException( "Illegal field name format, should be '<property> [by key|value]' but was '" + fieldName + "'", text, pos); 
    225     } 
    226  
    227     throw new OCommandSQLParsingException( "Illegal field name format, should be '<property> [by key|value]' but was '" + fieldName + "'", text, pos); 
    228   } 
     210        private void checkMapIndexSpecifier(final String fieldName, final String text, final int pos) { 
     211                String[] fieldNameParts = fieldName.split("\\s+"); 
     212                if (fieldNameParts.length == 1) 
     213                        return; 
     214 
     215                if (fieldNameParts.length == 3) { 
     216                        if ("by".equals(fieldNameParts[1].toLowerCase())) { 
     217                                try { 
     218                                        OPropertyMapIndexDefinition.INDEX_BY.valueOf(fieldNameParts[2].toUpperCase()); 
     219                                } catch (IllegalArgumentException iae) { 
     220                                        throw new OCommandSQLParsingException("Illegal field name format, should be '<property> [by key|value]' but was '" 
     221                                                        + fieldName + "'", text, pos); 
     222                                } 
     223                                return; 
     224                        } 
     225                        throw new OCommandSQLParsingException("Illegal field name format, should be '<property> [by key|value]' but was '" 
     226                                        + fieldName + "'", text, pos); 
     227                } 
     228 
     229                throw new OCommandSQLParsingException("Illegal field name format, should be '<property> [by key|value]' but was '" + fieldName 
     230                                + "'", text, pos); 
     231        } 
     232 
     233        @Override 
     234        public String getSyntax() { 
     235                return "CREATE INDEX <name> [ON <class-name> (prop-names)] <type> [<key-type>]"; 
     236        } 
    229237} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLCreateLink.java

    r19299 r19635  
    4646 */ 
    4747@SuppressWarnings("unchecked") 
    48 public class OCommandExecutorSQLCreateLink extends OCommandExecutorSQLPermissionAbstract { 
     48public class OCommandExecutorSQLCreateLink extends OCommandExecutorSQLAbstract { 
    4949        public static final String      KEYWORD_CREATE  = "CREATE"; 
    5050        public static final String      KEYWORD_LINK            = "LINK"; 
     
    7171                int pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    7272                if (pos == -1 || !word.toString().equals(KEYWORD_CREATE)) 
    73                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_CREATE + " not found", text, oldPos); 
     73                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_CREATE + " not found. Use " + getSyntax(), text, oldPos); 
    7474 
    7575                oldPos = pos; 
    7676                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    7777                if (pos == -1 || !word.toString().equals(KEYWORD_LINK)) 
    78                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_LINK + " not found", text, oldPos); 
     78                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_LINK + " not found. Use " + getSyntax(), text, oldPos); 
    7979 
    8080                oldPos = pos; 
    8181                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, false); 
    8282                if (pos == -1) 
    83                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_FROM + " not found", text, oldPos); 
     83                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_FROM + " not found. Use " + getSyntax(), text, oldPos); 
    8484 
    8585                if (!word.toString().equalsIgnoreCase(KEYWORD_FROM)) { 
     
    9999 
    100100                        if (pos == -1) 
    101                                 throw new OCommandSQLParsingException("Link type missed", text, oldPos); 
     101                                throw new OCommandSQLParsingException("Link type missed. Use " + getSyntax(), text, oldPos); 
    102102 
    103103                        linkType = OType.valueOf(word.toString().toUpperCase(Locale.ENGLISH)); 
     
    108108 
    109109                if (pos == -1 || !word.toString().equals(KEYWORD_FROM)) 
    110                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_FROM + " not found", text, oldPos); 
     110                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_FROM + " not found. Use " + getSyntax(), text, oldPos); 
    111111 
    112112                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, false); 
    113113                if (pos == -1) 
    114                         throw new OCommandSQLParsingException("Expected <class>.<property>", text, pos); 
     114                        throw new OCommandSQLParsingException("Expected <class>.<property>. Use " + getSyntax(), text, pos); 
    115115 
    116116                String[] parts = word.toString().split("\\."); 
    117117                if (parts.length != 2) 
    118                         throw new OCommandSQLParsingException("Expected <class>.<property>", text, pos); 
     118                        throw new OCommandSQLParsingException("Expected <class>.<property>. Use " + getSyntax(), text, pos); 
    119119 
    120120                sourceClassName = parts[0]; 
     
    125125                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, true); 
    126126                if (pos == -1 || !word.toString().equals(KEYWORD_TO)) 
    127                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_TO + " not found", text, oldPos); 
     127                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_TO + " not found. Use " + getSyntax(), text, oldPos); 
    128128 
    129129                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, false); 
    130130                if (pos == -1) 
    131                         throw new OCommandSQLParsingException("Expected <class>.<property>", text, pos); 
     131                        throw new OCommandSQLParsingException("Expected <class>.<property>. Use " + getSyntax(), text, pos); 
    132132 
    133133                parts = word.toString().split("\\."); 
    134134                if (parts.length != 2) 
    135                         throw new OCommandSQLParsingException("Expected <class>.<property>", text, pos); 
     135                        throw new OCommandSQLParsingException("Expected <class>.<property>. Use " + getSyntax(), text, pos); 
    136136 
    137137                destClassName = parts[0]; 
     
    145145 
    146146                if (!word.toString().equalsIgnoreCase("INVERSE")) 
    147                         throw new OCommandSQLParsingException("Missed 'INVERSE'", text, pos); 
     147                        throw new OCommandSQLParsingException("Missed 'INVERSE'. Use " + getSyntax(), text, pos); 
    148148 
    149149                inverse = true; 
     
    319319                return total; 
    320320        } 
     321 
     322        @Override 
     323        public String getSyntax() { 
     324                return "CREATE LINK <link-name> [TYPE <link-type>] FROM <source-class>.<source-property> TO <destination-class>.<destination-property> [INVERSE]"; 
     325        } 
    321326} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLCreateProperty.java

    r19299 r19635  
    3636 */ 
    3737@SuppressWarnings("unchecked") 
    38 public class OCommandExecutorSQLCreateProperty extends OCommandExecutorSQLPermissionAbstract { 
     38public class OCommandExecutorSQLCreateProperty extends OCommandExecutorSQLAbstract { 
    3939        public static final String      KEYWORD_CREATE          = "CREATE"; 
    4040        public static final String      KEYWORD_PROPERTY        = "PROPERTY"; 
     
    128128                return sourceClass.properties().size(); 
    129129        } 
     130 
     131        @Override 
     132        public String getSyntax() { 
     133                return "CREATE PROPERTY <class>.<property> <type> [<linked-type>|<linked-class>]"; 
     134        } 
    130135} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLDelegate.java

    r19245 r19635  
    5252                return delegate.execute(iArgs); 
    5353        } 
     54 
     55        public String getSyntax() { 
     56                return delegate.getSyntax(); 
     57        } 
    5458} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLDelete.java

    r19299 r19635  
    6666                int pos = OSQLHelper.nextWord(text, textUpperCase, 0, word, true); 
    6767                if (pos == -1 || !word.toString().equals(OCommandExecutorSQLDelete.KEYWORD_DELETE)) 
    68                         throw new OCommandSQLParsingException("Keyword " + OCommandExecutorSQLDelete.KEYWORD_DELETE + " not found", text, 0); 
     68                        throw new OCommandSQLParsingException("Keyword " + OCommandExecutorSQLDelete.KEYWORD_DELETE + " not found. Use " 
     69                                        + getSyntax(), text, 0); 
    6970 
    7071                int oldPos = pos; 
    7172                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    7273                if (pos == -1 || !word.toString().equals(KEYWORD_FROM)) 
    73                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_FROM + " not found", text, oldPos); 
     74                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_FROM + " not found. Use " + getSyntax(), text, oldPos); 
    7475 
    7576                oldPos = pos; 
    7677                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    7778                if (pos == -1) 
    78                         throw new OCommandSQLParsingException("Invalid subject name. Expected cluster, class or index", text, oldPos); 
     79                        throw new OCommandSQLParsingException("Invalid subject name. Expected cluster, class or index. Use " + getSyntax(), text, 
     80                                        oldPos); 
    7981 
    8082                final String subjectName = word.toString(); 
     
    8385                        // INDEX 
    8486                        indexName = subjectName.substring(OCommandExecutorSQLAbstract.INDEX_PREFIX.length()); 
    85                         compiledFilter = OSQLEngine.getInstance().parseFromWhereCondition(text.substring(oldPos)); 
     87                        compiledFilter = OSQLEngine.getInstance().parseFromWhereCondition(text.substring(oldPos), context); 
    8688                } else { 
    8789                        query = database.command(new OSQLAsynchQuery<ODocument>("select from " + subjectName + " " + text.substring(pos), this)); 
     
    151153                return true; 
    152154        } 
     155 
     156        public String getSyntax() { 
     157                return "DELETE FROM <Class>|cluster:<cluster [WHERE <condition>*]"; 
     158        } 
    153159} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLDropClass.java

    r19299 r19635  
    3535 */ 
    3636@SuppressWarnings("unchecked") 
    37 public class OCommandExecutorSQLDropClass extends OCommandExecutorSQLPermissionAbstract { 
     37public class OCommandExecutorSQLDropClass extends OCommandExecutorSQLAbstract { 
    3838        public static final String      KEYWORD_DROP    = "DROP"; 
    3939        public static final String      KEYWORD_CLASS   = "CLASS"; 
     
    5151                int pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    5252                if (pos == -1 || !word.toString().equals(KEYWORD_DROP)) 
    53                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_DROP + " not found", text, oldPos); 
     53                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_DROP + " not found. Use " + getSyntax(), text, oldPos); 
    5454 
    5555                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, true); 
    5656                if (pos == -1 || !word.toString().equals(KEYWORD_CLASS)) 
    57                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_CLASS + " not found", text, oldPos); 
     57                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_CLASS + " not found. Use " + getSyntax(), text, oldPos); 
    5858 
    5959                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, false); 
    6060                if (pos == -1) 
    61                         throw new OCommandSQLParsingException("Expected <class>", text, pos); 
     61                        throw new OCommandSQLParsingException("Expected <class>. Use " + getSyntax(), text, pos); 
    6262 
    6363                className = word.toString(); 
    6464                if (className == null) 
    65                         throw new OCommandSQLParsingException("Class is null", text, pos); 
     65                        throw new OCommandSQLParsingException("Class is null. Use " + getSyntax(), text, pos); 
    6666 
    6767                return this; 
     
    115115                return true; 
    116116        } 
     117 
     118        @Override 
     119        public String getSyntax() { 
     120                return "DROP CLASS <class>"; 
     121        } 
    117122} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLDropIndex.java

    r19299 r19635  
    3030 */ 
    3131@SuppressWarnings("unchecked") 
    32 public class OCommandExecutorSQLDropIndex extends OCommandExecutorSQLPermissionAbstract { 
     32public class OCommandExecutorSQLDropIndex extends OCommandExecutorSQLAbstract { 
    3333        public static final String      KEYWORD_DROP    = "DROP"; 
    3434        public static final String      KEYWORD_INDEX   = "INDEX"; 
     
    4646                int pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    4747                if (pos == -1 || !word.toString().equals(KEYWORD_DROP)) 
    48                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_DROP + " not found", text, oldPos); 
     48                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_DROP + " not found. Use " + getSyntax(), text, oldPos); 
    4949 
    5050                oldPos = pos; 
    5151                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, true); 
    5252                if (pos == -1 || !word.toString().equals(KEYWORD_INDEX)) 
    53                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_INDEX + " not found", text, oldPos); 
     53                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_INDEX + " not found. Use " + getSyntax(), text, oldPos); 
    5454 
    5555                oldPos = pos; 
    5656                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, false); 
    5757                if (pos == -1) 
    58                         throw new OCommandSQLParsingException("Expected index name", text, oldPos); 
     58                        throw new OCommandSQLParsingException("Expected index name. Use " + getSyntax(), text, oldPos); 
    5959 
    6060                name = word.toString(); 
     
    7373                return null; 
    7474        } 
     75 
     76        @Override 
     77        public String getSyntax() { 
     78                return "DROP INDEX <index-name>|<class>.<property>"; 
     79        } 
    7580} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLDropProperty.java

    r19299 r19635  
    3737 */ 
    3838@SuppressWarnings("unchecked") 
    39 public class OCommandExecutorSQLDropProperty extends OCommandExecutorSQLPermissionAbstract { 
     39public class OCommandExecutorSQLDropProperty extends OCommandExecutorSQLAbstract { 
    4040        public static final String      KEYWORD_DROP                    = "DROP"; 
    4141        public static final String      KEYWORD_PROPERTY        = "PROPERTY"; 
     
    5555                int pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    5656                if (pos == -1 || !word.toString().equals(KEYWORD_DROP)) 
    57                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_DROP + " not found", text, oldPos); 
     57                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_DROP + " not found. Use " + getSyntax(), text, oldPos); 
    5858 
    5959                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, true); 
    6060                if (pos == -1 || !word.toString().equals(KEYWORD_PROPERTY)) 
    61                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_PROPERTY + " not found", text, oldPos); 
     61                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_PROPERTY + " not found. Use " + getSyntax(), text, oldPos); 
    6262 
    6363                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, false); 
    6464                if (pos == -1) 
    65                         throw new OCommandSQLParsingException("Expected <class>.<property>", text, pos); 
     65                        throw new OCommandSQLParsingException("Expected <class>.<property>. Use " + getSyntax(), text, pos); 
    6666 
    6767                String[] parts = word.toString().split("\\."); 
    6868                if (parts.length != 2) 
    69                         throw new OCommandSQLParsingException("Expected <class>.<property>", text, pos); 
     69                        throw new OCommandSQLParsingException("Expected <class>.<property>. Use " + getSyntax(), text, pos); 
    7070 
    7171                className = parts[0]; 
     
    147147                return result; 
    148148        } 
     149 
     150        @Override 
     151        public String getSyntax() { 
     152                return "DROP PROPERTY <class>.<property>"; 
     153        } 
    149154} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLFindReferences.java

    r19299 r19635  
    5151 */ 
    5252@SuppressWarnings("unchecked") 
    53 public class OCommandExecutorSQLFindReferences extends OCommandExecutorSQLPermissionAbstract { 
     53public class OCommandExecutorSQLFindReferences extends OCommandExecutorSQLAbstract { 
    5454        public static final String      KEYWORD_FIND                            = "FIND"; 
    5555        public static final String      KEYWORD_REFERENCES      = "REFERENCES"; 
     
    6868                int pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    6969                if (pos == -1 || !word.toString().equals(KEYWORD_FIND)) 
    70                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_FIND + " not found", text, oldPos); 
     70                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_FIND + " not found. Use " + getSyntax(), text, oldPos); 
    7171 
    7272                oldPos = pos; 
    7373                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    7474                if (pos == -1 || !word.toString().equals(KEYWORD_REFERENCES)) 
    75                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_REFERENCES + " not found", text, oldPos); 
     75                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_REFERENCES + " not found. Use " + getSyntax(), text, oldPos); 
    7676 
    7777                oldPos = pos; 
    7878                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, false); 
    7979                if (pos == -1) 
    80                         throw new OCommandSQLParsingException("Expected <recordId>", text, oldPos); 
     80                        throw new OCommandSQLParsingException("Expected <recordId>. Use " + getSyntax(), text, oldPos); 
    8181 
    8282                final String recordIdString = word.toString(); 
    8383                if (recordIdString == null || recordIdString.equals("")) 
    84                         throw new OCommandSQLParsingException("Record to search cannot be null", text, pos); 
     84                        throw new OCommandSQLParsingException("Record to search cannot be null. Use " + getSyntax(), text, pos); 
    8585                try { 
    8686                        recordId = new ORecordId(recordIdString); 
     
    9797                        classList = word.toString().trim(); 
    9898                        if (!classList.startsWith("[") || !classList.endsWith("]")) { 
    99                                 throw new OCommandSQLParsingException("Class list must be contained in []", text, pos); 
     99                                throw new OCommandSQLParsingException("Class list must be contained in []. Use " + getSyntax(), text, pos); 
    100100                        } 
    101101                        classList = classList.substring(1, classList.length() - 1); 
     
    211211                } 
    212212        } 
     213 
     214        @Override 
     215        public String getSyntax() { 
     216                return "FIND REFERENCES <rid> [class-list]"; 
     217        } 
    213218} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLGrant.java

    r19299 r19635  
    4848                int pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    4949                if (pos == -1 || !word.toString().equals(KEYWORD_GRANT)) 
    50                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_GRANT + " not found", text, oldPos); 
     50                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_GRANT + " not found. Use " + getSyntax(), text, oldPos); 
    5151 
    5252                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, true); 
     
    5858                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, true); 
    5959                if (pos == -1 || !word.toString().equals(KEYWORD_ON)) 
    60                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_ON + " not found", text, oldPos); 
     60                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_ON + " not found. Use " + getSyntax(), text, oldPos); 
    6161 
    6262                pos = OSQLHelper.nextWord(text, text, pos, word, true); 
     
    6868                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, true); 
    6969                if (pos == -1 || !word.toString().equals(KEYWORD_TO)) 
    70                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_TO + " not found", text, oldPos); 
     70                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_TO + " not found. Use " + getSyntax(), text, oldPos); 
    7171 
    7272                pos = OSQLHelper.nextWord(text, text, pos, word, true); 
     
    9393                return role; 
    9494        } 
     95 
     96        public String getSyntax() { 
     97                return "GRANT <permission> ON <resource> TO <role>"; 
     98        } 
    9599} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLInsert.java

    r19299 r19635  
    6262                int pos = OSQLHelper.nextWord(text, textUpperCase, 0, word, true); 
    6363                if (pos == -1 || !word.toString().equals(OCommandExecutorSQLInsert.KEYWORD_INSERT)) 
    64                         throw new OCommandSQLParsingException("Keyword " + OCommandExecutorSQLInsert.KEYWORD_INSERT + " not found", text, 0); 
     64                        throw new OCommandSQLParsingException("Keyword " + OCommandExecutorSQLInsert.KEYWORD_INSERT + " not found. Use " 
     65                                        + getSyntax(), text, 0); 
    6566 
    6667                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, true); 
    6768                if (pos == -1 || !word.toString().equals(KEYWORD_INTO)) 
    68                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_INTO + " not found", text, 0); 
     69                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_INTO + " not found. Use " + getSyntax(), text, 0); 
    6970 
    7071                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, true); 
    7172                if (pos == -1) 
    72                         throw new OCommandSQLParsingException("Invalid subject name. Expected cluster, class or index", text, pos); 
     73                        throw new OCommandSQLParsingException("Invalid subject name. Expected cluster, class or index. Use " + getSyntax(), text, pos); 
    7374 
    7475                String subjectName = word.toString(); 
     
    9697                final int beginFields = OStringParser.jumpWhiteSpaces(text, pos); 
    9798                if (beginFields == -1 || text.charAt(beginFields) != '(') 
    98                         throw new OCommandSQLParsingException("Set of fields is missed. Example: (name, surname)", text, pos); 
     99                        throw new OCommandSQLParsingException("Set of fields is missed. Example: (name, surname). Use " + getSyntax(), text, pos); 
    99100 
    100101                final int endFields = text.indexOf(')', beginFields + 1); 
    101102                if (endFields == -1) 
    102                         throw new OCommandSQLParsingException("Missed closed brace", text, beginFields); 
     103                        throw new OCommandSQLParsingException("Missed closed brace. Use " + getSyntax(), text, beginFields); 
    103104 
    104105                final ArrayList<String> fieldNames = new ArrayList<String>(); 
    105106                OStringSerializerHelper.getParameters(text, beginFields, endFields, fieldNames); 
    106107                if (fieldNames.size() == 0) 
    107                         throw new OCommandSQLParsingException("Set of fields is empty. Example: (name, surname)", text, endFields); 
     108                        throw new OCommandSQLParsingException("Set of fields is empty. Example: (name, surname). Use " + getSyntax(), text, endFields); 
    108109 
    109110                // REMOVE QUOTATION MARKS IF ANY 
     
    113114                pos = OSQLHelper.nextWord(text, textUpperCase, endFields + 1, word, true); 
    114115                if (pos == -1 || !word.toString().equals(KEYWORD_VALUES)) 
    115                         throw new OCommandSQLParsingException("Missed VALUES keyword", text, endFields); 
     116                        throw new OCommandSQLParsingException("Missed VALUES keyword. Use " + getSyntax(), text, endFields); 
    116117 
    117118                final int beginValues = OStringParser.jumpWhiteSpaces(text, pos); 
    118119                if (pos == -1 || text.charAt(beginValues) != '(') 
    119                         throw new OCommandSQLParsingException("Set of values is missed. Example: ('Bill', 'Stuart', 300)", text, pos); 
     120                        throw new OCommandSQLParsingException("Set of values is missed. Example: ('Bill', 'Stuart', 300). Use " + getSyntax(), text, 
     121                                        pos); 
    120122 
    121123                final int endValues = text.lastIndexOf(')'); 
    122124                if (endValues == -1) 
    123                         throw new OCommandSQLParsingException("Missed closed brace", text, beginValues); 
     125                        throw new OCommandSQLParsingException("Missed closed brace. Use " + getSyntax(), text, beginValues); 
    124126 
    125127                final List<String> values = OStringSerializerHelper.smartSplit(text, new char[] { ',' }, beginValues + 1, endValues - 1, true); 
    126128 
    127129                if (values.size() == 0) 
    128                         throw new OCommandSQLParsingException("Set of values is empty. Example: ('Bill', 'Stuart', 300)", text, beginValues); 
     130                        throw new OCommandSQLParsingException("Set of values is empty. Example: ('Bill', 'Stuart', 300). Use " + getSyntax(), text, 
     131                                        beginValues); 
    129132 
    130133                if (values.size() != fieldNames.size()) 
     
    134137                final Object[] fieldValues = new Object[values.size()]; 
    135138                for (int i = 0; i < values.size(); ++i) 
    136                         fieldValues[i] = OSQLHelper.parseValue(this, OStringSerializerHelper.decode(values.get(i).trim())); 
     139                        fieldValues[i] = OSQLHelper.parseValue(this, OStringSerializerHelper.decode(values.get(i).trim()), context); 
    137140 
    138141                fields = new LinkedHashMap<String, Object>(); 
     
    171174                } 
    172175        } 
     176 
     177        @Override 
     178        public String getSyntax() { 
     179                return "INSERT INTO <Class>|cluster:<cluster>|index:<index> (<field>[,]*) VALUES (<expression>[,]*)"; 
     180        } 
    173181} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLRebuildIndex.java

    r19299 r19635  
    3232 */ 
    3333@SuppressWarnings("unchecked") 
    34 public class OCommandExecutorSQLRebuildIndex extends OCommandExecutorSQLPermissionAbstract { 
     34public class OCommandExecutorSQLRebuildIndex extends OCommandExecutorSQLAbstract { 
    3535        public static final String      KEYWORD_REBUILD = "REBUILD"; 
    3636        public static final String      KEYWORD_INDEX           = "INDEX"; 
     
    4848                int pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    4949                if (pos == -1 || !word.toString().equals(KEYWORD_REBUILD)) 
    50                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_REBUILD + " not found", text, oldPos); 
     50                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_REBUILD + " not found. Use " + getSyntax(), text, oldPos); 
    5151 
    5252                oldPos = pos; 
    5353                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, true); 
    5454                if (pos == -1 || !word.toString().equals(KEYWORD_INDEX)) 
    55                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_INDEX + " not found", text, oldPos); 
     55                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_INDEX + " not found. Use " + getSyntax(), text, oldPos); 
    5656 
    5757                oldPos = pos; 
     
    9494                } 
    9595        } 
     96 
     97        @Override 
     98        public String getSyntax() { 
     99                return "REBUILD INDEX <index-name>"; 
     100        } 
    96101} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLRevoke.java

    r19299 r19635  
    5050                int pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    5151                if (pos == -1 || !word.toString().equals(KEYWORD_REVOKE)) 
    52                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_REVOKE + " not found", text, oldPos); 
     52                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_REVOKE + " not found. Use " + getSyntax(), text, oldPos); 
    5353 
    5454                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, true); 
     
    6060                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, true); 
    6161                if (pos == -1 || !word.toString().equals(KEYWORD_ON)) 
    62                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_ON + " not found", text, oldPos); 
     62                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_ON + " not found. Use " + getSyntax(), text, oldPos); 
    6363 
    6464                pos = OSQLHelper.nextWord(text, text, pos, word, true); 
     
    7070                pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, true); 
    7171                if (pos == -1 || !word.toString().equals(KEYWORD_FROM)) 
    72                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_FROM + " not found", text, oldPos); 
     72                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_FROM + " not found. Use " + getSyntax(), text, oldPos); 
    7373 
    7474                pos = OSQLHelper.nextWord(text, text, pos, word, true); 
     
    9595                return role; 
    9696        } 
     97 
     98        public String getSyntax() { 
     99                return "REVOKE <permission> ON <resource> FROM <role>"; 
     100        } 
    97101} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLSelect.java

    r19431 r19635  
    1616package com.orientechnologies.orient.core.sql; 
    1717 
    18 import java.util.*; 
     18import java.util.ArrayList; 
     19import java.util.Collection; 
     20import java.util.Collections; 
     21import java.util.Comparator; 
     22import java.util.Iterator; 
     23import java.util.LinkedHashMap; 
     24import java.util.List; 
     25import java.util.Locale; 
     26import java.util.Map; 
    1927import java.util.Map.Entry; 
     28import java.util.Set; 
    2029 
    2130import com.orientechnologies.common.collection.OCompositeKey; 
     
    3140import com.orientechnologies.orient.core.exception.OQueryParsingException; 
    3241import com.orientechnologies.orient.core.exception.ORecordNotFoundException; 
    33 import com.orientechnologies.orient.core.id.ORID; 
    34 import com.orientechnologies.orient.core.id.ORecordId; 
    3542import com.orientechnologies.orient.core.index.OCompositeIndexDefinition; 
    3643import com.orientechnologies.orient.core.index.OIndex; 
     
    4653import com.orientechnologies.orient.core.record.ORecord; 
    4754import com.orientechnologies.orient.core.record.ORecordInternal; 
    48 import com.orientechnologies.orient.core.record.ORecordSchemaAware; 
    4955import com.orientechnologies.orient.core.record.impl.ODocument; 
    5056import com.orientechnologies.orient.core.record.impl.ODocumentHelper; 
    5157import com.orientechnologies.orient.core.serialization.serializer.OStringSerializerHelper; 
    52 import com.orientechnologies.orient.core.sql.filter.OSQLFilter; 
    5358import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
    5459import com.orientechnologies.orient.core.sql.filter.OSQLFilterItem; 
    5560import com.orientechnologies.orient.core.sql.filter.OSQLFilterItemField; 
    5661import com.orientechnologies.orient.core.sql.functions.OSQLFunctionRuntime; 
    57 import com.orientechnologies.orient.core.sql.operator.*; 
    58 import com.orientechnologies.orient.core.sql.query.OSQLAsynchQuery; 
    59 import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery; 
    60 import com.orientechnologies.orient.core.storage.ORecordBrowsingListener; 
    61 import com.orientechnologies.orient.core.storage.OStorageEmbedded; 
     62import com.orientechnologies.orient.core.sql.operator.OIndexReuseType; 
     63import com.orientechnologies.orient.core.sql.operator.OQueryOperator; 
     64import com.orientechnologies.orient.core.sql.operator.OQueryOperatorBetween; 
     65import com.orientechnologies.orient.core.sql.operator.OQueryOperatorContains; 
     66import com.orientechnologies.orient.core.sql.operator.OQueryOperatorContainsKey; 
     67import com.orientechnologies.orient.core.sql.operator.OQueryOperatorContainsText; 
     68import com.orientechnologies.orient.core.sql.operator.OQueryOperatorContainsValue; 
     69import com.orientechnologies.orient.core.sql.operator.OQueryOperatorEquals; 
     70import com.orientechnologies.orient.core.sql.operator.OQueryOperatorIn; 
     71import com.orientechnologies.orient.core.sql.operator.OQueryOperatorMajor; 
     72import com.orientechnologies.orient.core.sql.operator.OQueryOperatorMajorEquals; 
     73import com.orientechnologies.orient.core.sql.operator.OQueryOperatorMinor; 
     74import com.orientechnologies.orient.core.sql.operator.OQueryOperatorMinorEquals; 
    6275import com.orientechnologies.orient.core.type.tree.OMVRBTreeRIDSet; 
    6376 
     
    7083 */ 
    7184@SuppressWarnings("unchecked") 
    72 public class OCommandExecutorSQLSelect extends OCommandExecutorSQLAbstract implements ORecordBrowsingListener { 
    73         private static final String                                                                                     KEYWORD_AS                                              = " AS "; 
    74         public static final String                                                                                      KEYWORD_SELECT                          = "SELECT"; 
    75         public static final String                                                                                      KEYWORD_ASC                                             = "ASC"; 
    76         public static final String                                                                                      KEYWORD_DESC                                    = "DESC"; 
    77         public static final String                                                                                      KEYWORD_ORDER                                   = "ORDER"; 
    78         public static final String                                                                                      KEYWORD_BY                                              = "BY"; 
    79         public static final String                                                                                      KEYWORD_ORDER_BY                        = "ORDER BY"; 
    80         private static final String                                                                                     KEYWORD_FROM_2FIND              = " " + KEYWORD_FROM + " "; 
    81  
    82         private OSQLAsynchQuery<ORecordSchemaAware<?>>  request; 
    83         private OSQLFilter                                                                                                                      compiledFilter; 
    84         private Map<String, Object>                                                                                     projections                                             = null; 
    85         private List<OPair<String, String>>                                                     orderedFields; 
    86         private List<OIdentifiable>                                                                                     tempResult; 
    87         private int                                                                                                                                                     resultCount; 
    88         private Object                                                                                                                                  flattenTarget; 
    89         private boolean                                                                                                                                 anyFunctionAggregates   = false; 
    90         private int                                                                                                                                                     fetchLimit                                              = -1; 
    91  
    92         /** 
    93          * Presents query subset in form of field1 = "field1 value" AND field2 = "field2 value" ... AND fieldN anyOpetator "fieldN value" 
    94          *  
    95          * Where pairs (field1, value1) ... (fieldn-1, valuen-1) are stored in {@link #fieldValuePairs} map but last pair is stored in 
    96          * {@link #lastField} {@link #lastValue} properties and their operator will be stored in {@link #lastOperator} property. 
    97          *  
    98          * Such data structure is used because from composite index point of view any "field and value" pairs can be reordered to match 
    99          * keys order that is used in index in case all fields and values are related to each other using equals operator, but position of 
    100          * field - value pair that uses non equals operator cannot be changed. Actually only one non-equals operator can be used for 
    101          * composite index search and filed - value pair that uses this index should always be placed at last position. 
    102          */ 
    103         private static final class OIndexSearchResult { 
    104                 private final Map<String, Object>       fieldValuePairs = new HashMap<String, Object>(); 
    105                 private final OQueryOperator                    lastOperator; 
    106                 private final OSQLFilterItemField.FieldChain lastField; 
    107                 private final Object                                                    lastValue; 
    108  
    109                 private OIndexSearchResult(final OQueryOperator lastOperator, final OSQLFilterItemField.FieldChain field, final Object value) { 
    110                         this.lastOperator = lastOperator; 
    111                         lastField = field; 
    112                         lastValue = value; 
    113                 } 
    114  
    115                 /** 
    116                  * Combines two queries subset into one. This operation will be valid only if {@link #canBeMerged(OIndexSearchResult)} method 
    117                  * will return <code>true</code> for the same passed in parameter. 
    118                  *  
    119                  * @param searchResult 
    120                  *          Query subset to merge. 
    121                  * @return New instance that presents merged query. 
    122                  */ 
    123                 private OIndexSearchResult merge(final OIndexSearchResult searchResult) { 
    124                         final OQueryOperator operator; 
    125                         final OIndexSearchResult result; 
    126  
    127             if (searchResult.lastOperator instanceof OQueryOperatorEquals) { 
    128                 result = new OIndexSearchResult(this.lastOperator, lastField, lastValue); 
    129                 result.fieldValuePairs.putAll(searchResult.fieldValuePairs); 
    130                 result.fieldValuePairs.putAll(fieldValuePairs); 
    131                 result.fieldValuePairs.put(searchResult.lastField.getItemName(0), searchResult.lastValue); 
    132             } else { 
    133                 operator = searchResult.lastOperator; 
    134                 result = new OIndexSearchResult(operator, searchResult.lastField, searchResult.lastValue); 
    135                 result.fieldValuePairs.putAll(searchResult.fieldValuePairs); 
    136                 result.fieldValuePairs.putAll(fieldValuePairs); 
    137                 result.fieldValuePairs.put(lastField.getItemName(0), lastValue); 
    138             } 
    139             return result; 
    140                 } 
    141  
    142                 /** 
    143                  * @param searchResult 
    144                  *          Query subset is going to be merged with given one. 
    145                  * @return <code>true</code> if two query subsets can be merged. 
    146                  */ 
    147                 private boolean canBeMerged(final OIndexSearchResult searchResult) { 
    148             if (lastField.isLong() || searchResult.lastField.isLong()) { 
    149                 return false; 
    150             } 
    151                         return (lastOperator instanceof OQueryOperatorEquals) || (searchResult.lastOperator instanceof OQueryOperatorEquals); 
    152                 } 
    153  
    154                 private List<String> fields() { 
    155                         final List<String> result = new ArrayList<String>(fieldValuePairs.size() + 1); 
    156                         result.addAll(fieldValuePairs.keySet()); 
    157                         result.add(lastField.getItemName(0)); 
    158                         return result; 
    159                 } 
    160  
    161                 private int getFieldCount() { 
    162                         return fieldValuePairs.size() + 1; 
    163                 } 
    164         } 
     85public class OCommandExecutorSQLSelect extends OCommandExecutorSQLExtractAbstract { 
     86        private static final String                                     KEYWORD_AS                                              = " AS "; 
     87        public static final String                                      KEYWORD_SELECT                          = "SELECT"; 
     88        public static final String                                      KEYWORD_ASC                                             = "ASC"; 
     89        public static final String                                      KEYWORD_DESC                                    = "DESC"; 
     90        public static final String                                      KEYWORD_ORDER                                   = "ORDER"; 
     91        public static final String                                      KEYWORD_BY                                              = "BY"; 
     92        public static final String                                      KEYWORD_ORDER_BY                        = "ORDER BY"; 
     93 
     94        private Map<String, Object>                                     projections                                             = null; 
     95        private List<OPair<String, String>>     orderedFields; 
     96        private Object                                                                                  flattenTarget; 
     97        private boolean                                                                                 anyFunctionAggregates   = false; 
     98        private int                                                                                                     fetchLimit                                              = -1; 
    16599 
    166100        /** 
     
    168102         */ 
    169103        public OCommandExecutorSQLSelect parse(final OCommandRequestText iRequest) { 
    170                 final ODatabaseRecord database = getDatabase(); 
    171                 database.checkSecurity(ODatabaseSecurityResources.COMMAND, ORole.PERMISSION_READ); 
    172  
    173                 init(iRequest.getText()); 
    174  
    175                 if (iRequest instanceof OSQLSynchQuery) { 
    176                         request = (OSQLSynchQuery<ORecordSchemaAware<?>>) iRequest; 
    177                 } else if (iRequest instanceof OSQLAsynchQuery) 
    178                         request = (OSQLAsynchQuery<ORecordSchemaAware<?>>) iRequest; 
    179                 else { 
    180                         // BUILD A QUERY OBJECT FROM THE COMMAND REQUEST 
    181                         request = new OSQLSynchQuery<ORecordSchemaAware<?>>(iRequest.getText()); 
    182                         if (iRequest.getResultListener() != null) 
    183                                 request.setResultListener(iRequest.getResultListener()); 
    184                 } 
     104                super.parse(iRequest); 
    185105 
    186106                final int pos = parseProjections(); 
     
    197117                        endPosition = endP; 
    198118 
    199                 compiledFilter = OSQLEngine.getInstance().parseFromWhereCondition(text.substring(pos, endPosition)); 
     119                compiledFilter = OSQLEngine.getInstance().parseFromWhereCondition(text.substring(pos, endPosition), context); 
    200120 
    201121                optimize(); 
     
    228148 
    229149        public Object execute(final Map<Object, Object> iArgs) { 
    230                 parameters = iArgs; 
    231  
    232                 // TODO: SUPPORT MULTIPLE CLASSES LIKE A SQL JOIN 
    233                 compiledFilter.bindParameters(iArgs); 
    234  
    235150                fetchLimit = getQueryFetchLimit(); 
    236151 
    237                 if (compiledFilter.getTargetClasses() != null) 
    238                         searchInClasses(); 
    239                 else if (compiledFilter.getTargetClusters() != null) 
    240                         searchInClusters(); 
    241                 else if (compiledFilter.getTargetIndex() != null) 
    242                         searchInIndex(); 
    243                 else if (compiledFilter.getTargetRecords() != null) 
    244                         searchInRecords(); 
    245                 else 
    246                         throw new OQueryParsingException("No source found in query: specify class, clusters or single records"); 
     152                if (!assignTarget(iArgs)) { 
     153                        if (compiledFilter.getTargetIndex() != null) 
     154                                searchInIndex(); 
     155                        else 
     156                                throw new OQueryParsingException("No source found in query: specify class, cluster(s), index or single record(s). Use " 
     157                                                + getSyntax()); 
     158                } 
     159 
     160                executeSearch(); 
    247161 
    248162                applyFlatten(); 
     
    251165                applyLimit(); 
    252166 
    253                 if (tempResult != null) { 
    254                         for (OIdentifiable d : tempResult) 
    255                                 if (d != null) 
    256                                         request.getResultListener().result(d); 
    257                 } 
    258  
    259                 if (request instanceof OSQLSynchQuery) 
    260                         return ((OSQLSynchQuery<ORecordSchemaAware<?>>) request).getResult(); 
    261  
    262                 return null; 
    263         } 
    264  
    265         public boolean foreach(final ORecordInternal<?> iRecord) { 
    266                 if (iRecord != null) 
    267                         if (filter(iRecord)) 
    268                                 return addResult(iRecord); 
    269  
    270                 return true; 
     167                return handleResult(); 
     168        } 
     169 
     170        protected void executeSearch() { 
     171                if (target == null) 
     172                        // SEARCH WITHOUT USING TARGET (USUALLY WHEN INDEXES ARE INVOLVED) 
     173                        return; 
     174 
     175                // BROWSE ALL THE RECORDS 
     176                for (OIdentifiable id : target) { 
     177                        final ORecordInternal<?> record = (ORecordInternal<?>) id.getRecord(); 
     178 
     179                        if (record != null && record.getRecordType() != ODocument.RECORD_TYPE) 
     180                                // WRONG RECORD TYPE: JUMP IT 
     181                                continue; 
     182 
     183                        if (filter(record)) 
     184                                if (!addResult(record)) 
     185                                        // END OF EXECUTION 
     186                                        break; 
     187                } 
    271188        } 
    272189 
     
    384301        } 
    385302 
    386         /** 
    387          * Parses the limit keyword if found. 
    388          *  
    389          * @param word 
    390          *          StringBuilder to parse 
    391          * @return 
    392          * @return the limit found as integer, or -1 if no limit is found. -1 means no limits. 
    393          * @throws OCommandSQLParsingException 
    394          *           if no valid limit has been found 
    395          */ 
    396         protected int parseLimit(final StringBuilder word) throws OCommandSQLParsingException { 
    397                 if (!word.toString().equals(KEYWORD_LIMIT)) 
    398                         return -1; 
    399  
    400                 currentPos = OSQLHelper.nextWord(text, textUpperCase, currentPos, word, true); 
    401                 try { 
    402                         limit = Integer.parseInt(word.toString()); 
    403                 } catch (Exception e) { 
    404                         throw new OCommandSQLParsingException("Invalid LIMIT value setted to '" + word 
    405                                         + "' but it should be a valid integer. Example: LIMIT 10", text, currentPos); 
    406                 } 
    407                 return limit; 
     303        @Override 
     304        protected void searchInClasses() { 
     305                final OClass cls = compiledFilter.getTargetClasses().keySet().iterator().next(); 
     306 
     307                if (searchForIndexes(cls)) 
     308                        OProfiler.getInstance().updateCounter("Query.indexUsage", 1); 
     309                else 
     310                        super.searchInClasses(); 
    408311        } 
    409312 
    410313        @SuppressWarnings("rawtypes") 
    411314        private boolean searchForIndexes(final OClass iSchemaClass) { 
     315                final ODatabaseRecord database = getDatabase(); 
     316                database.checkSecurity(ODatabaseSecurityResources.CLASS, ORole.PERMISSION_READ, iSchemaClass.getName().toLowerCase()); 
     317 
    412318                // Create set that is sorted by amount of fields in OIndexSearchResult items 
    413319                // so the most specific restrictions will be processed first. 
     
    463369 
    464370                                if (indexDefinition.getParamCount() == 1) { 
    465                 if (indexCanBeUsedInEqualityOperators && operator instanceof OQueryOperatorBetween) { 
     371                                        if (indexCanBeUsedInEqualityOperators && operator instanceof OQueryOperatorBetween) { 
    466372                                                final Object[] betweenKeys = (Object[]) keyParams.get(0); 
    467373 
    468                                                 final Object keyOne = indexDefinition.createValue( Collections.singletonList( OSQLHelper.getValue( betweenKeys[0] ) ) ); 
    469                                                 final Object keyTwo = indexDefinition.createValue( Collections.singletonList( OSQLHelper.getValue( betweenKeys[2] ) ) ); 
     374                                                final Object keyOne = indexDefinition.createValue(Collections.singletonList(OSQLHelper.getValue(betweenKeys[0]))); 
     375                                                final Object keyTwo = indexDefinition.createValue(Collections.singletonList(OSQLHelper.getValue(betweenKeys[2]))); 
    470376 
    471377                                                if (keyOne == null || keyTwo == null) 
     
    488394                                                boolean containsNotCompatibleKey = false; 
    489395                                                for (final Object keyValue : inParams) { 
    490                                                         final Object key = indexDefinition.createValue( OSQLHelper.getValue( keyValue ) ); 
     396                                                        final Object key = indexDefinition.createValue(OSQLHelper.getValue(keyValue)); 
    491397                                                        if (key == null) { 
    492398                                                                containsNotCompatibleKey = true; 
     
    511417 
    512418                                        final Object key; 
    513           if(indexDefinition instanceof OIndexDefinitionMultiValue) 
    514             key = ((OIndexDefinitionMultiValue)indexDefinition).createSingleValue( keyParams.get( 0 ) ); 
    515           else  
    516             key = indexDefinition.createValue( keyParams ); 
     419                                        if (indexDefinition instanceof OIndexDefinitionMultiValue) 
     420                                                key = ((OIndexDefinitionMultiValue) indexDefinition).createSingleValue(keyParams.get(0)); 
     421                                        else 
     422                                                key = indexDefinition.createValue(keyParams); 
    517423 
    518424                                        if (key == null) 
     
    532438                                        } 
    533439 
    534           if(operator instanceof OQueryOperatorContainsKey) { 
    535             if((index.getDefinition() instanceof OPropertyMapIndexDefinition) && 
    536               ((OPropertyMapIndexDefinition) index.getDefinition()).getIndexBy() == OPropertyMapIndexDefinition.INDEX_BY.KEY) { 
    537               fillSearchIndexResultSet(index.get(key)); 
    538               return true; 
    539             } 
    540             continue; 
    541           } 
    542  
    543           if(operator instanceof OQueryOperatorContainsValue) { 
    544             if((index.getDefinition() instanceof OPropertyMapIndexDefinition) && 
    545               ((OPropertyMapIndexDefinition) index.getDefinition()).getIndexBy() == OPropertyMapIndexDefinition.INDEX_BY.VALUE) { 
    546               fillSearchIndexResultSet(index.get(key)); 
    547               return true; 
    548             } 
    549             continue; 
    550           } 
    551  
    552           if(operator instanceof OQueryOperatorContains) { 
    553             fillSearchIndexResultSet(index.get(key)); 
    554             return true; 
    555           } 
     440                                        if (operator instanceof OQueryOperatorContainsKey) { 
     441                                                if ((index.getDefinition() instanceof OPropertyMapIndexDefinition) 
     442                                                                && ((OPropertyMapIndexDefinition) index.getDefinition()).getIndexBy() == OPropertyMapIndexDefinition.INDEX_BY.KEY) { 
     443                                                        fillSearchIndexResultSet(index.get(key)); 
     444                                                        return true; 
     445                                                } 
     446                                                continue; 
     447                                        } 
     448 
     449                                        if (operator instanceof OQueryOperatorContainsValue) { 
     450                                                if ((index.getDefinition() instanceof OPropertyMapIndexDefinition) 
     451                                                                && ((OPropertyMapIndexDefinition) index.getDefinition()).getIndexBy() == OPropertyMapIndexDefinition.INDEX_BY.VALUE) { 
     452                                                        fillSearchIndexResultSet(index.get(key)); 
     453                                                        return true; 
     454                                                } 
     455                                                continue; 
     456                                        } 
     457 
     458                                        if (operator instanceof OQueryOperatorContains) { 
     459                                                fillSearchIndexResultSet(index.get(key)); 
     460                                                return true; 
     461                                        } 
    556462 
    557463                                        if (operator instanceof OQueryOperatorMajor) { 
     
    623529                                                betweenKeyTwoParams.add(betweenKeyTwo); 
    624530 
    625                                                 final Object keyOne = indexDefinition.createValue( betweenKeyOneParams ); 
     531                                                final Object keyOne = indexDefinition.createValue(betweenKeyOneParams); 
    626532 
    627533                                                if (keyOne == null) 
    628534                                                        continue; 
    629535 
    630                                                 final Object keyTwo = indexDefinition.createValue( betweenKeyTwoParams ); 
     536                                                final Object keyTwo = indexDefinition.createValue(betweenKeyTwoParams); 
    631537 
    632538                                                if (keyTwo == null) 
     
    653559                                                // using part of composite key stored in index. 
    654560 
    655                                                 final Object keyOne = indexDefinition.createValue( keyParams ); 
     561                                                final Object keyOne = indexDefinition.createValue(keyParams); 
    656562 
    657563                                                if (keyOne == null) 
    658564                                                        continue; 
    659565 
    660                                                 final Object keyTwo = indexDefinition.createValue( keyParams ); 
     566                                                final Object keyTwo = indexDefinition.createValue(keyParams); 
    661567 
    662568                                                final Collection<OIdentifiable> result; 
     
    681587                                                // is the biggest composite key in the index that contains key with value field1=1. 
    682588 
    683                                                 final Object keyOne = indexDefinition.createValue( keyParams ); 
     589                                                final Object keyOne = indexDefinition.createValue(keyParams); 
    684590 
    685591                                                if (keyOne == null) 
    686592                                                        continue; 
    687593 
    688                                                 final Object keyTwo = indexDefinition.createValue( keyParams.subList( 0, keyParams.size() - 1 ) ); 
     594                                                final Object keyTwo = indexDefinition.createValue(keyParams.subList(0, keyParams.size() - 1)); 
    689595 
    690596                                                if (keyTwo == null) 
     
    712618                                                // is the biggest composite key in the index that contains key with value field1=1. 
    713619 
    714                                                 final Object keyOne = indexDefinition.createValue( keyParams ); 
     620                                                final Object keyOne = indexDefinition.createValue(keyParams); 
    715621 
    716622                                                if (keyOne == null) 
    717623                                                        continue; 
    718624 
    719                                                 final Object keyTwo = indexDefinition.createValue( keyParams.subList( 0, keyParams.size() - 1 ) ); 
     625                                                final Object keyTwo = indexDefinition.createValue(keyParams.subList(0, keyParams.size() - 1)); 
    720626 
    721627                                                if (keyTwo == null) 
     
    743649                                                // is the biggest composite key in the index that contains key with values field1=1 and field2=2. 
    744650 
    745                                                 final Object keyOne = indexDefinition.createValue( keyParams.subList( 0, keyParams.size() - 1 ) ); 
     651                                                final Object keyOne = indexDefinition.createValue(keyParams.subList(0, keyParams.size() - 1)); 
    746652 
    747653                                                if (keyOne == null) 
    748654                                                        continue; 
    749655 
    750                                                 final Object keyTwo = indexDefinition.createValue( keyParams ); 
     656                                                final Object keyTwo = indexDefinition.createValue(keyParams); 
    751657 
    752658                                                if (keyTwo == null) 
     
    774680                                                // is the biggest composite key in the index that contains key with value field1=1 and field2=2. 
    775681 
    776                                                 final Object keyOne = indexDefinition.createValue( keyParams.subList( 0, keyParams.size() - 1 ) ); 
     682                                                final Object keyOne = indexDefinition.createValue(keyParams.subList(0, keyParams.size() - 1)); 
    777683 
    778684                                                if (keyOne == null) 
    779685                                                        continue; 
    780686 
    781                                                 final Object keyTwo = indexDefinition.createValue( keyParams ); 
     687                                                final Object keyTwo = indexDefinition.createValue(keyParams); 
    782688 
    783689                                                if (keyTwo == null) 
     
    804710        } 
    805711 
    806     private List<OIndex<?>> getInvolvedIndexes(OClass iSchemaClass, OIndexSearchResult searchResultFields) { 
    807             final Set<OIndex<?>> involvedIndexes = iSchemaClass.getInvolvedIndexes(searchResultFields.fields()); 
    808  
    809             final List<OIndex<?>> result = new ArrayList<OIndex<?>>(involvedIndexes.size()); 
    810         for (OIndex<?> involvedIndex : involvedIndexes) { 
    811             if (searchResultFields.lastField.isLong()) { 
    812                 result.addAll( OIndexProxy.createdProxy(involvedIndex, searchResultFields.lastField, getDatabase()) ); 
    813             } else { 
    814                 result.add(involvedIndex); 
    815             } 
    816         } 
    817  
    818         return result; 
    819     } 
    820  
    821     private OIndexSearchResult analyzeQueryBranch(final OClass iSchemaClass, final OSQLFilterCondition iCondition, 
     712        private List<OIndex<?>> getInvolvedIndexes(OClass iSchemaClass, OIndexSearchResult searchResultFields) { 
     713                final Set<OIndex<?>> involvedIndexes = iSchemaClass.getInvolvedIndexes(searchResultFields.fields()); 
     714 
     715                final List<OIndex<?>> result = new ArrayList<OIndex<?>>(involvedIndexes.size()); 
     716                for (OIndex<?> involvedIndex : involvedIndexes) { 
     717                        if (searchResultFields.lastField.isLong()) { 
     718                                result.addAll(OIndexProxy.createdProxy(involvedIndex, searchResultFields.lastField, getDatabase())); 
     719                        } else { 
     720                                result.add(involvedIndex); 
     721                        } 
     722                } 
     723 
     724                return result; 
     725        } 
     726 
     727        private OIndexSearchResult analyzeQueryBranch(final OClass iSchemaClass, final OSQLFilterCondition iCondition, 
    822728                        final List<OIndexSearchResult> iIndexSearchResults) { 
    823729                if (iCondition == null) 
     
    857763                                return null; 
    858764 
    859             if (checkIndexExistence(iSchemaClass, result)) 
     765                        if (checkIndexExistence(iSchemaClass, result)) 
    860766                                iIndexSearchResults.add(result); 
    861767 
     
    933839        } 
    934840 
    935         protected boolean filter(final ORecordInternal<?> iRecord) { 
    936                 return compiledFilter.evaluate(iRecord); 
    937         } 
    938  
    939841        protected int parseProjections() { 
    940842                int currentPos = 0; 
     
    995897                                        if (pars.size() != 1) 
    996898                                                throw new OCommandSQLParsingException("FLATTEN operator expects the field name as parameter. Example FLATTEN( out )"); 
    997                                         flattenTarget = OSQLHelper.parseValue(this, pars.get(0).trim()); 
     899                                        flattenTarget = OSQLHelper.parseValue(this, pars.get(0).trim(), context); 
    998900 
    999901                                        // BY PASS THIS AS PROJECTION BUT TREAT IT AS SPECIAL 
     
    1007909                                } 
    1008910 
    1009                                 projectionValue = OSQLHelper.parseValue(this, projection); 
     911                                projectionValue = OSQLHelper.parseValue(this, projection, context); 
    1010912                                projections.put(fieldName, projectionValue); 
    1011913 
     
    1046948        } 
    1047949 
    1048   private void scanEntireClusters(final int[] clusterIds) { 
    1049     final OSQLFilterCondition rootCondition = compiledFilter.getRootCondition(); 
    1050  
    1051     final ODatabaseRecord database = getDatabase(); 
    1052     final ORID beginRange; 
    1053     final ORID endRange; 
    1054  
    1055     if (rootCondition == null) { 
    1056       if (request instanceof OSQLSynchQuery) 
    1057         beginRange = ((OSQLSynchQuery) request).getNextPageRID(); 
    1058       else 
    1059         beginRange = null; 
    1060       endRange = null; 
    1061     } else { 
    1062       final ORID conditionBeginRange = rootCondition.getBeginRidRange(); 
    1063       final ORID conditionEndRange = rootCondition.getEndRidRange(); 
    1064       final ORID nextPageRid; 
    1065  
    1066       if (request instanceof OSQLSynchQuery) 
    1067         nextPageRid = ((OSQLSynchQuery) request).getNextPageRID(); 
    1068       else 
    1069         nextPageRid = null; 
    1070  
    1071       if(conditionBeginRange != null && nextPageRid != null) 
    1072         beginRange = conditionBeginRange.compareTo(nextPageRid) > 0 ? conditionBeginRange : nextPageRid; 
    1073       else if(conditionBeginRange != null) 
    1074         beginRange = conditionBeginRange; 
    1075       else 
    1076         beginRange = nextPageRid; 
    1077  
    1078       endRange = conditionEndRange; 
    1079     } 
    1080  
    1081     ((OStorageEmbedded) database.getStorage()).browse(clusterIds, beginRange, 
    1082             endRange, this, (ORecordInternal<?>) database.newInstance(), false); 
    1083   } 
    1084  
    1085   private void applyOrderBy() { 
     950        private void applyOrderBy() { 
    1086951                if (orderedFields == null) 
    1087952                        return; 
     
    1103968                        for (OIdentifiable id : tempResult) { 
    1104969                                if (flattenTarget instanceof OSQLFilterItem) 
    1105                                         fieldValue = ((OSQLFilterItem) flattenTarget).getValue((ORecordInternal<?>) id.getRecord()); 
     970                                        fieldValue = ((OSQLFilterItem) flattenTarget).getValue((ORecordInternal<?>) id.getRecord(), context); 
    1106971                                else if (flattenTarget instanceof OSQLFunctionRuntime) 
    1107972                                        fieldValue = ((OSQLFunctionRuntime) flattenTarget).getResult(); 
     
    11361001                                        value = null; 
    11371002                                } else if (projection.getValue() instanceof OSQLFilterItemField) 
    1138                                         value = ((OSQLFilterItemField) projection.getValue()).getValue(doc); 
     1003                                        value = ((OSQLFilterItemField) projection.getValue()).getValue(doc, null); 
    11391004                                else if (projection.getValue() instanceof OSQLFunctionRuntime) { 
    11401005                                        final OSQLFunctionRuntime f = (OSQLFunctionRuntime) projection.getValue(); 
     
    11601025                // INVOKE THE LISTENER 
    11611026                return iRecord; 
    1162         } 
    1163  
    1164         private void searchInClasses() { 
    1165                 final int[] clusterIds; 
    1166                 final OClass cls = compiledFilter.getTargetClasses().keySet().iterator().next(); 
    1167  
    1168                 final ODatabaseRecord database = getDatabase(); 
    1169                 database.checkSecurity(ODatabaseSecurityResources.CLASS, ORole.PERMISSION_READ, cls.getName()); 
    1170  
    1171                 clusterIds = cls.getPolymorphicClusterIds(); 
    1172  
    1173                 // CHECK PERMISSION TO ACCESS TO ALL THE CONFIGURED CLUSTERS 
    1174                 for (final int clusterId : clusterIds) 
    1175                         database.checkSecurity(ODatabaseSecurityResources.CLUSTER, ORole.PERMISSION_READ, database.getClusterNameById(clusterId)); 
    1176  
    1177                 if (searchForIndexes(cls)) 
    1178                         OProfiler.getInstance().updateCounter("Query.indexUsage", 1); 
    1179                 else 
    1180                         // NO INDEXES: SCAN THE ENTIRE CLUSTER 
    1181                         scanEntireClusters(clusterIds); 
    1182         } 
    1183  
    1184         private void searchInClusters() { 
    1185                 final int[] clusterIds; 
    1186                 String firstCluster = compiledFilter.getTargetClusters().keySet().iterator().next(); 
    1187  
    1188                 if (firstCluster == null || firstCluster.length() == 0) 
    1189                         throw new OCommandExecutionException("No cluster or schema class selected in query"); 
    1190  
    1191                 final ODatabaseRecord database = getDatabase(); 
    1192  
    1193                 if (Character.isDigit(firstCluster.charAt(0))) 
    1194                         // GET THE CLUSTER NUMBER 
    1195                         clusterIds = OStringSerializerHelper.splitIntArray(firstCluster); 
    1196                 else 
    1197                         // GET THE CLUSTER NUMBER BY THE CLASS NAME 
    1198                         clusterIds = new int[] { database.getClusterIdByName(firstCluster.toLowerCase()) }; 
    1199  
    1200                 database.checkSecurity(ODatabaseSecurityResources.CLUSTER, ORole.PERMISSION_READ, firstCluster.toLowerCase()); 
    1201  
    1202                 scanEntireClusters(clusterIds); 
    1203         } 
    1204  
    1205         private void searchInRecords() { 
    1206                 ORecordId rid = new ORecordId(); 
    1207                 ORecordInternal<?> record; 
    1208                 final ODatabaseRecord database = getDatabase(); 
    1209                 for (String rec : compiledFilter.getTargetRecords()) { 
    1210                         rid.fromString(rec); 
    1211                         record = database.load(rid); 
    1212                         final boolean continueResultParsing = foreach(record); 
    1213                         if (!continueResultParsing) 
    1214                                 break; 
    1215                 } 
    12161027        } 
    12171028 
     
    13291140                                        keyParams.add(OSQLHelper.getValue(o)); 
    13301141                                } 
    1331                                 return indexDefinition.createValue( keyParams ); 
     1142                                return indexDefinition.createValue(keyParams); 
    13321143                        } else { 
    13331144                                value = OSQLHelper.getValue(value); 
     
    13351146                                        return value; 
    13361147                                } else { 
    1337                                         return indexDefinition.createValue( value ); 
     1148                                        return indexDefinition.createValue(value); 
    13381149                                } 
    13391150                        } 
     
    13661177                        for (Entry<String, Object> projection : projections.entrySet()) { 
    13671178                                if (projection.getValue() instanceof OSQLFilterItemField) 
    1368                                         value = ((OSQLFilterItemField) projection.getValue()).getValue(result); 
     1179                                        value = ((OSQLFilterItemField) projection.getValue()).getValue(result, null); 
    13691180                                else if (projection.getValue() instanceof OSQLFunctionRuntime) { 
    13701181                                        final OSQLFunctionRuntime f = (OSQLFunctionRuntime) projection.getValue(); 
     
    13801191        } 
    13811192 
    1382         private void applyLimit() { 
    1383                 if (tempResult != null && limit > 0) { 
    1384                         final List<OIdentifiable> newList = new ArrayList<OIdentifiable>(); 
    1385  
    1386                         // APPLY LIMIT 
    1387                         final int tot = Math.min(limit, tempResult.size()); 
    1388                         for (int i = 0; i < tot; ++i) 
    1389                                 newList.add(tempResult.get(i)); 
    1390  
    1391                         tempResult.clear(); 
    1392                         tempResult = newList; 
    1393                 } 
    1394         } 
    1395  
    1396         public List<OIdentifiable> getResult() { 
    1397                 if (tempResult != null) 
    1398                         return tempResult; 
    1399  
    1400                 if (request instanceof OSQLSynchQuery) 
    1401                         return (List<OIdentifiable>) ((OSQLSynchQuery<ORecordSchemaAware<?>>) request).getResult(); 
    1402  
    1403                 return null; 
    1404         } 
    1405  
    1406     private boolean checkIndexExistence(OClass iSchemaClass, OIndexSearchResult result) { 
    1407         if (!iSchemaClass.areIndexed(result.fields())) { 
    1408             return false; 
    1409         } 
    1410  
    1411         if (result.lastField.isLong()) { 
    1412             final int fieldCount = result.lastField.getItemCount(); 
    1413             OClass oClass = iSchemaClass.getProperty(result.lastField.getItemName(0)).getLinkedClass(); 
    1414  
    1415             for (int i = 1; i < fieldCount; i++) { 
    1416                 if (!oClass.areIndexed(result.lastField.getItemName(i))) { 
    1417                     return false; 
    1418                 } 
    1419  
    1420                 oClass = oClass.getProperty(result.lastField.getItemName(i)).getLinkedClass(); 
    1421             } 
    1422         } 
    1423         return true; 
    1424     } 
    1425  
    1426     /** 
    1427          * Optimizes the contidion tree. 
    1428          */ 
    1429         private void optimize() { 
    1430                 if (compiledFilter == null) 
    1431                         return; 
    1432  
    1433                 optimizeBranch(null, compiledFilter.getRootCondition()); 
    1434         } 
    1435  
    1436         private void optimizeBranch(final OSQLFilterCondition iParentCondition, OSQLFilterCondition iCondition) { 
    1437                 if (iCondition == null) 
    1438                         return; 
    1439  
    1440                 final Object left = iCondition.getLeft(); 
    1441  
    1442                 if (left instanceof OSQLFilterCondition) 
    1443                         // ANALYSE LEFT RECURSIVELY 
    1444                         optimizeBranch(iCondition, (OSQLFilterCondition) left); 
    1445  
    1446                 final Object right = iCondition.getRight(); 
    1447  
    1448                 if (right instanceof OSQLFilterCondition) 
    1449                         // ANALYSE RIGHT RECURSIVELY 
    1450                         optimizeBranch(iCondition, (OSQLFilterCondition) right); 
    1451  
    1452                 final OQueryOperator oper = iCondition.getOperator(); 
    1453  
    1454                 Object result = null; 
    1455  
    1456                 if (left instanceof OSQLFilterItemField && right instanceof OSQLFilterItemField) { 
    1457                         if (((OSQLFilterItemField) left).getRoot().equals(((OSQLFilterItemField) right).getRoot())) { 
    1458                                 if (oper instanceof OQueryOperatorEquals) 
    1459                                         result = Boolean.TRUE; 
    1460                                 else if (oper instanceof OQueryOperatorNotEquals) 
    1461                                         result = Boolean.FALSE; 
    1462                         } 
    1463                 } 
    1464  
    1465                 if (result != null) { 
    1466                         if (iParentCondition != null) 
    1467                                 if (iCondition == iParentCondition.getLeft()) 
    1468                                         // REPLACE LEFT 
    1469                                         iCondition.setLeft(result); 
    1470                                 else 
    1471                                         // REPLACE RIGHT 
    1472                                         iCondition.setRight(result); 
    1473                         else { 
    1474                                 // REPLACE ROOT CONDITION 
    1475                                 if (result instanceof Boolean && ((Boolean) result)) 
    1476                                         compiledFilter.setRootCondition(null); 
    1477                         } 
    1478                 } 
     1193        private boolean checkIndexExistence(OClass iSchemaClass, OIndexSearchResult result) { 
     1194                if (!iSchemaClass.areIndexed(result.fields())) { 
     1195                        return false; 
     1196                } 
     1197 
     1198                if (result.lastField.isLong()) { 
     1199                        final int fieldCount = result.lastField.getItemCount(); 
     1200                        OClass oClass = iSchemaClass.getProperty(result.lastField.getItemName(0)).getLinkedClass(); 
     1201 
     1202                        for (int i = 1; i < fieldCount; i++) { 
     1203                                if (!oClass.areIndexed(result.lastField.getItemName(i))) { 
     1204                                        return false; 
     1205                                } 
     1206 
     1207                                oClass = oClass.getProperty(result.lastField.getItemName(i)).getLinkedClass(); 
     1208                        } 
     1209                } 
     1210                return true; 
     1211        } 
     1212 
     1213        @Override 
     1214        public String getSyntax() { 
     1215                return "SELECT [<Projections>] FROM <Target> [WHERE <Condition>*] [ORDER BY <Fields>* [ASC|DESC]*] [LIMIT <MaxRecords>]"; 
    14791216        } 
    14801217} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLTruncateClass.java

    r19299 r19635  
    3232 *  
    3333 */ 
    34 public class OCommandExecutorSQLTruncateClass extends OCommandExecutorSQLPermissionAbstract { 
     34public class OCommandExecutorSQLTruncateClass extends OCommandExecutorSQLAbstract { 
    3535        public static final String      KEYWORD_TRUNCATE        = "TRUNCATE"; 
    3636        public static final String      KEYWORD_CLASS                   = "CLASS"; 
     
    4848                int pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    4949                if (pos == -1 || !word.toString().equals(KEYWORD_TRUNCATE)) 
    50                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_TRUNCATE + " not found", text, oldPos); 
     50                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_TRUNCATE + " not found. Use " + getSyntax(), text, oldPos); 
    5151 
    5252                oldPos = pos; 
    5353                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    5454                if (pos == -1 || !word.toString().equals(KEYWORD_CLASS)) 
    55                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_CLASS + " not found", text, oldPos); 
     55                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_CLASS + " not found. Use " + getSyntax(), text, oldPos); 
    5656 
    5757                oldPos = pos; 
    5858                pos = OSQLHelper.nextWord(text, text, oldPos, word, true); 
    5959                if (pos == -1) 
    60                         throw new OCommandSQLParsingException("Expected class name", text, oldPos); 
     60                        throw new OCommandSQLParsingException("Expected class name. Use " + getSyntax(), text, oldPos); 
    6161 
    6262                final String className = word.toString(); 
     
    8686                return recs; 
    8787        } 
     88 
     89        @Override 
     90        public String getSyntax() { 
     91                return "TRUNCATE CLASS <class-name>"; 
     92        } 
    8893} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLTruncateCluster.java

    r19299 r19635  
    3333 *  
    3434 */ 
    35 public class OCommandExecutorSQLTruncateCluster extends OCommandExecutorSQLPermissionAbstract { 
     35public class OCommandExecutorSQLTruncateCluster extends OCommandExecutorSQLAbstract { 
    3636        public static final String      KEYWORD_TRUNCATE        = "TRUNCATE"; 
    3737        public static final String      KEYWORD_CLUSTER         = "CLUSTER"; 
     
    4949                int pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    5050                if (pos == -1 || !word.toString().equals(KEYWORD_TRUNCATE)) 
    51                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_TRUNCATE + " not found", text, oldPos); 
     51                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_TRUNCATE + " not found. Use " + getSyntax(), text, oldPos); 
    5252 
    5353                oldPos = pos; 
    5454                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    5555                if (pos == -1 || !word.toString().equals(KEYWORD_CLUSTER)) 
    56                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_CLUSTER + " not found", text, oldPos); 
     56                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_CLUSTER + " not found. Use " + getSyntax(), text, oldPos); 
    5757 
    5858                oldPos = pos; 
    5959                pos = OSQLHelper.nextWord(text, text, oldPos, word, true); 
    6060                if (pos == -1) 
    61                         throw new OCommandSQLParsingException("Expected cluster name", text, oldPos); 
     61                        throw new OCommandSQLParsingException("Expected cluster name. Use " + getSyntax(), text, oldPos); 
    6262 
    6363                clusterName = word.toString(); 
     
    8787                return recs; 
    8888        } 
     89 
     90        @Override 
     91        public String getSyntax() { 
     92                return "TRUNCATE CLUSTER <cluster-name>"; 
     93        } 
    8994} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLTruncateRecord.java

    r19431 r19635  
    3535 *  
    3636 */ 
    37 public class OCommandExecutorSQLTruncateRecord extends OCommandExecutorSQLPermissionAbstract { 
     37public class OCommandExecutorSQLTruncateRecord extends OCommandExecutorSQLAbstract { 
    3838        public static final String      KEYWORD_TRUNCATE        = "TRUNCATE"; 
    3939        public static final String      KEYWORD_RECORD          = "RECORD"; 
     
    5050                int pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    5151                if (pos == -1 || !word.toString().equals(KEYWORD_TRUNCATE)) 
    52                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_TRUNCATE + " not found", text, oldPos); 
     52                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_TRUNCATE + " not found. Use " + getSyntax(), text, oldPos); 
    5353 
    5454                oldPos = pos; 
    5555                pos = OSQLHelper.nextWord(text, textUpperCase, oldPos, word, true); 
    5656                if (pos == -1 || !word.toString().equals(KEYWORD_RECORD)) 
    57                         throw new OCommandSQLParsingException("Keyword " + KEYWORD_RECORD + " not found", text, oldPos); 
     57                        throw new OCommandSQLParsingException("Keyword " + KEYWORD_RECORD + " not found. Use " + getSyntax(), text, oldPos); 
    5858 
    5959                oldPos = pos; 
    6060                pos = OSQLHelper.nextWord(text, text, oldPos, word, true); 
    6161                if (pos == -1) 
    62                         throw new OCommandSQLParsingException("Expected one or more records", text, oldPos); 
     62                        throw new OCommandSQLParsingException("Expected one or more records. Use " + getSyntax(), text, oldPos); 
    6363 
    6464                if (word.charAt(0) == '[') 
     
    7070 
    7171                if (records.isEmpty()) 
    72                         throw new OCommandSQLParsingException("Missed record(s)", text, oldPos); 
     72                        throw new OCommandSQLParsingException("Missed record(s). Use " + getSyntax(), text, oldPos); 
    7373                return this; 
    7474        } 
     
    9393                return records.size(); 
    9494        } 
     95 
     96        @Override 
     97        public String getSyntax() { 
     98                return "TRUNCATE RECORD <rid>*"; 
     99        } 
    95100} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLUpdate.java

    r19299 r19635  
    7878                int pos = OSQLHelper.nextWord(text, textUpperCase, 0, word, true); 
    7979                if (pos == -1 || !word.toString().equals(OCommandExecutorSQLUpdate.KEYWORD_UPDATE)) 
    80                         throw new OCommandSQLParsingException("Keyword " + OCommandExecutorSQLUpdate.KEYWORD_UPDATE + " not found", text, 0); 
     80                        throw new OCommandSQLParsingException("Keyword " + OCommandExecutorSQLUpdate.KEYWORD_UPDATE + " not found. Use " 
     81                                        + getSyntax(), text, 0); 
    8182 
    8283                int newPos = OSQLHelper.nextWord(text, textUpperCase, pos, word, true); 
    8384                if (newPos == -1) 
    84                         throw new OCommandSQLParsingException("Invalid target", text, pos); 
     85                        throw new OCommandSQLParsingException("Invalid target. Use " + getSyntax(), text, pos); 
    8586 
    8687                pos = newPos; 
     
    9394                                                .toString().equals(KEYWORD_REMOVE))) 
    9495                        throw new OCommandSQLParsingException("Expected keyword " + KEYWORD_SET + "," + KEYWORD_ADD + "," + KEYWORD_PUT + " or " 
    95                                         + KEYWORD_REMOVE, text, pos); 
     96                                        + KEYWORD_REMOVE + ". Use " + getSyntax(), text, pos); 
    9697 
    9798                pos = newPos; 
     
    186187 
    187188                        if (v instanceof OSQLFilterItem) 
    188                                 v = ((OSQLFilterItem) v).getValue(record); 
     189                                v = ((OSQLFilterItem) v).getValue(record, context); 
    189190                        else if (v instanceof OSQLFunctionRuntime) 
    190191                                v = ((OSQLFunctionRuntime) v).execute(record, this); 
     
    219220 
    220221                                if (pair.getValue() instanceof OSQLFilterItem) 
    221                                         pair.setValue(((OSQLFilterItem) pair.getValue()).getValue(record)); 
     222                                        pair.setValue(((OSQLFilterItem) pair.getValue()).getValue(record, null)); 
    222223                                else if (pair.getValue() instanceof OSQLFunctionRuntime) 
    223224                                        v = ((OSQLFunctionRuntime) pair.getValue()).execute(record, this); 
     
    310311                        newPos = OSQLHelper.nextWord(text, textUpperCase, pos, word, false); 
    311312                        if (newPos == -1) 
    312                                 throw new OCommandSQLParsingException("Field name expected", text, pos); 
     313                                throw new OCommandSQLParsingException("Field name expected. Use " + getSyntax(), text, pos); 
    313314                        pos = newPos; 
    314315 
     
    318319 
    319320                        if (newPos == -1 || text.charAt(newPos) != '=') 
    320                                 throw new OCommandSQLParsingException("Character '=' was expected", text, pos); 
     321                                throw new OCommandSQLParsingException("Character '=' was expected. Use " + getSyntax(), text, pos); 
    321322 
    322323                        pos = newPos; 
    323324                        newPos = OSQLHelper.nextWord(text, textUpperCase, pos + 1, word, false, " =><"); 
    324325                        if (pos == -1) 
    325                                 throw new OCommandSQLParsingException("Value expected", text, pos); 
     326                                throw new OCommandSQLParsingException("Value expected. Use " + getSyntax(), text, pos); 
    326327 
    327328                        fieldValue = word.toString(); 
     
    340341 
    341342                if (addEntries.size() == 0) 
    342                         throw new OCommandSQLParsingException("Entries to add <field> = <value> are missed. Example: name = 'Bill', salary = 300.2", 
    343                                         text, pos); 
     343                        throw new OCommandSQLParsingException( 
     344                                        "Entries to add <field> = <value> are missed. Example: name = 'Bill', salary = 300.2. Use " + getSyntax(), text, pos); 
    344345 
    345346                return pos; 
     
    355356                        newPos = OSQLHelper.nextWord(text, textUpperCase, pos, word, false); 
    356357                        if (newPos == -1) 
    357                                 throw new OCommandSQLParsingException("Field name expected", text, pos); 
     358                                throw new OCommandSQLParsingException("Field name expected. Use " + getSyntax(), text, pos); 
    358359                        pos = newPos; 
    359360 
     
    363364 
    364365                        if (newPos == -1 || text.charAt(newPos) != '=') 
    365                                 throw new OCommandSQLParsingException("Character '=' was expected", text, pos); 
     366                                throw new OCommandSQLParsingException("Character '=' was expected. Use " + getSyntax(), text, pos); 
    366367 
    367368                        pos = newPos; 
    368369                        newPos = OSQLHelper.nextWord(text, textUpperCase, pos + 1, word, false, " =><,"); 
    369370                        if (pos == -1) 
    370                                 throw new OCommandSQLParsingException("Key expected", text, pos); 
     371                                throw new OCommandSQLParsingException("Key expected. Use " + getSyntax(), text, pos); 
    371372 
    372373                        fieldKey = word.toString(); 
     
    380381                                newPos = OStringParser.jumpWhiteSpaces(text, pos); 
    381382                                if (newPos == -1 || text.charAt(pos) != ',') 
    382                                         throw new OCommandSQLParsingException("',' expected", text, pos); 
     383                                        throw new OCommandSQLParsingException("',' expected. Use " + getSyntax(), text, pos); 
    383384 
    384385                                pos = newPos; 
     
    387388                        newPos = OSQLHelper.nextWord(text, textUpperCase, pos + 1, word, false, " =><,"); 
    388389                        if (pos == -1) 
    389                                 throw new OCommandSQLParsingException("Value expected", text, pos); 
     390                                throw new OCommandSQLParsingException("Value expected. Use " + getSyntax(), text, pos); 
    390391 
    391392                        fieldValue = word.toString(); 
     
    405406 
    406407                if (putEntries.size() == 0) 
    407                         throw new OCommandSQLParsingException("Entries to put <field> = <key>, <value> are missed. Example: name = 'Bill', 30", text, 
    408                                         pos); 
     408                        throw new OCommandSQLParsingException("Entries to put <field> = <key>, <value> are missed. Example: name = 'Bill', 30. Use " 
     409                                        + getSyntax(), text, pos); 
    409410 
    410411                return pos; 
     
    420421                        newPos = OSQLHelper.nextWord(text, textUpperCase, pos, word, false); 
    421422                        if (newPos == -1) 
    422                                 throw new OCommandSQLParsingException("Field name expected", text, pos); 
     423                                throw new OCommandSQLParsingException("Field name expected. Use " + getSyntax(), text, pos); 
    423424 
    424425                        fieldName = word.toString(); 
     
    429430                                pos = OSQLHelper.nextWord(text, textUpperCase, pos + 1, word, false, " =><,"); 
    430431                                if (pos == -1) 
    431                                         throw new OCommandSQLParsingException("Value expected", text, pos); 
     432                                        throw new OCommandSQLParsingException("Value expected. Use " + getSyntax(), text, pos); 
    432433 
    433434                                fieldValue = word.toString(); 
     
    451452 
    452453                if (removeEntries.size() == 0) 
    453                         throw new OCommandSQLParsingException("Field(s) to remove are missed. Example: name, salary", text, pos); 
     454                        throw new OCommandSQLParsingException("Field(s) to remove are missed. Example: name, salary. Use " + getSyntax(), text, pos); 
    454455                return pos; 
    455456        } 
     
    458459                if (fieldValue.trim().equals("?")) 
    459460                        parameterCounter++; 
    460                 return OSQLHelper.parseValue(this, fieldValue); 
     461                return OSQLHelper.parseValue(this, fieldValue, context); 
     462        } 
     463 
     464        @Override 
     465        public String getSyntax() { 
     466                return "UPDATE <class>|cluster:<cluster>> [SET|ADD|PUT|REMOVE] [[,] <field-name> = <field-value>]* [WHERE <conditions>]"; 
    461467        } 
    462468} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OSQLEngine.java

    r19431 r19635  
    2020import java.util.Map; 
    2121 
     22import com.orientechnologies.orient.core.command.OCommandContext; 
    2223import com.orientechnologies.orient.core.exception.OCommandExecutionException; 
    2324import com.orientechnologies.orient.core.sql.filter.OSQLFilter; 
     
    4647import com.orientechnologies.orient.core.sql.operator.OQueryOperatorEquals; 
    4748import com.orientechnologies.orient.core.sql.operator.OQueryOperatorIn; 
     49import com.orientechnologies.orient.core.sql.operator.OQueryOperatorInstanceof; 
    4850import com.orientechnologies.orient.core.sql.operator.OQueryOperatorIs; 
    4951import com.orientechnologies.orient.core.sql.operator.OQueryOperatorLike; 
     
    6769        private Map<String, Class<? extends OSQLFunction>>                                                                      aggregationFunctions    = new HashMap<String, Class<? extends OSQLFunction>>(); 
    6870        protected Map<String, Class<? extends OCommandExecutorSQLAbstract>>     commands                                                        = new HashMap<String, Class<? extends OCommandExecutorSQLAbstract>>(); 
    69         public static OQueryOperator[]                                                                                                                                                  RECORD_OPERATORS                        = { new OQueryOperatorAnd(), 
    70                         new OQueryOperatorOr(), new OQueryOperatorNotEquals(), new OQueryOperatorNot(), new OQueryOperatorEquals(), 
     71 
     72        // WARNING: ORDER IS IMPORTANT TO AVOID SUB-STRING LIKE "IS" and AND "INSTANCEOF": INSTANCEOF MUST BE PLACED BEFORE! AND ALSO FOR 
     73        // PERFORMANCE (MOST USED BEFORE) 
     74        public static OQueryOperator[]                                                                                                                                                  RECORD_OPERATORS                        = { new OQueryOperatorEquals(), 
     75                        new OQueryOperatorAnd(), new OQueryOperatorOr(), new OQueryOperatorNotEquals(), new OQueryOperatorNot(), 
    7176                        new OQueryOperatorMinorEquals(), new OQueryOperatorMinor(), new OQueryOperatorMajorEquals(), new OQueryOperatorContainsAll(), 
    72                         new OQueryOperatorMajor(), new OQueryOperatorLike(), new OQueryOperatorMatches(), new OQueryOperatorIs(), 
    73                         new OQueryOperatorIn(), new OQueryOperatorContainsKey(), new OQueryOperatorContainsValue(), new OQueryOperatorContainsText(), 
    74                         new OQueryOperatorContains(), new OQueryOperatorContainsText(), new OQueryOperatorTraverse(), new OQueryOperatorBetween(), 
    75                         new OQueryOperatorPlus(), new OQueryOperatorMinus(), new OQueryOperatorMultiply(), new OQueryOperatorDivide(), 
    76                         new OQueryOperatorMod()                                                                                                                                                                                                                                                 }; 
     77                        new OQueryOperatorMajor(), new OQueryOperatorLike(), new OQueryOperatorMatches(), new OQueryOperatorInstanceof(), 
     78                        new OQueryOperatorIs(), new OQueryOperatorIn(), new OQueryOperatorContainsKey(), new OQueryOperatorContainsValue(), 
     79                        new OQueryOperatorContainsText(), new OQueryOperatorContains(), new OQueryOperatorContainsText(), 
     80                        new OQueryOperatorTraverse(), new OQueryOperatorBetween(), new OQueryOperatorPlus(), new OQueryOperatorMinus(), 
     81                        new OQueryOperatorMultiply(), new OQueryOperatorDivide(), new OQueryOperatorMod()               }; 
    7782 
    7883        protected static OSQLEngine                                                                                                                                                                     INSTANCE                                                        = new OSQLEngine(); 
     
    8388                                OCommandExecutorSQLAlterDatabase.class); 
    8489                commands.put(OCommandExecutorSQLSelect.KEYWORD_SELECT, OCommandExecutorSQLSelect.class); 
     90                commands.put(OCommandExecutorSQLTraverse.KEYWORD_TRAVERSE, OCommandExecutorSQLTraverse.class); 
    8591                commands.put(OCommandExecutorSQLInsert.KEYWORD_INSERT, OCommandExecutorSQLInsert.class); 
    8692                commands.put(OCommandExecutorSQLUpdate.KEYWORD_UPDATE, OCommandExecutorSQLUpdate.class); 
     
    206212        } 
    207213 
    208         public OSQLFilter parseFromWhereCondition(final String iText) { 
    209                 return new OSQLFilter(iText); 
     214        public OSQLFilter parseFromWhereCondition(final String iText, final OCommandContext iContext) { 
     215                return new OSQLFilter(iText, iContext); 
    210216        } 
    211217 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/OSQLHelper.java

    r19299 r19635  
    2525 
    2626import com.orientechnologies.common.parser.OStringParser; 
     27import com.orientechnologies.orient.core.command.OCommandContext; 
    2728import com.orientechnologies.orient.core.command.OCommandToParse; 
    2829import com.orientechnologies.orient.core.id.ORID; 
     
    3738import com.orientechnologies.orient.core.sql.filter.OSQLFilterItemField; 
    3839import com.orientechnologies.orient.core.sql.filter.OSQLFilterItemParameter; 
     40import com.orientechnologies.orient.core.sql.filter.OSQLFilterItemVariable; 
    3941import com.orientechnologies.orient.core.sql.functions.OSQLFunctionRuntime; 
    4042 
     
    8486         * @return The value converted if recognized, otherwise VALUE_NOT_PARSED 
    8587         */ 
    86         public static Object parseValue(String iValue) { 
     88        public static Object parseValue(String iValue, final OCommandContext iContext) { 
    8789                if (iValue == null) 
    8890                        return null; 
     
    103105                        final List<Object> coll = new ArrayList<Object>(); 
    104106                        for (String item : items) { 
    105                                 coll.add(parseValue(item)); 
     107                                coll.add(parseValue(item, iContext)); 
    106108                        } 
    107109                        fieldValue = coll; 
     
    120122                                        throw new OCommandSQLParsingException("Map found but entries are not defined as <key>:<value>"); 
    121123 
    122                                 map.put(parseValue(parts.get(0)), parseValue(parts.get(1))); 
     124                                map.put(parseValue(parts.get(0), iContext), parseValue(parts.get(1), iContext)); 
    123125                        } 
    124126                        fieldValue = map; 
     
    175177        } 
    176178 
    177         public static Object parseValue(final OSQLFilter iSQLFilter, final OCommandToParse iCommand, final String iWord) { 
     179        public static Object parseValue(final OSQLFilter iSQLFilter, final OCommandToParse iCommand, final String iWord, 
     180                        final OCommandContext iContext) { 
    178181                if (iWord.charAt(0) == OStringSerializerHelper.PARAMETER_POSITIONAL 
    179182                                || iWord.charAt(0) == OStringSerializerHelper.PARAMETER_NAMED) { 
     
    183186                                return new OSQLFilterItemParameter(iWord); 
    184187                } else 
    185                         return parseValue(iCommand, iWord); 
    186         } 
    187  
    188         public static Object parseValue(final OCommandToParse iCommand, final String iWord) { 
     188                        return parseValue(iCommand, iWord, iContext); 
     189        } 
     190 
     191        public static Object parseValue(final OCommandToParse iCommand, final String iWord, final OCommandContext iContext) { 
    189192                if (iWord.equals("*")) 
    190193                        return "*"; 
    191194 
    192195                // TRY TO PARSE AS RAW VALUE 
    193                 final Object v = parseValue(iWord); 
     196                final Object v = parseValue(iWord, iContext); 
    194197                if (v != VALUE_NOT_PARSED) 
    195198                        return v; 
     
    199202                if (func != null) 
    200203                        return func; 
     204 
     205                if (iWord.startsWith("$")) 
     206                        // CONTEXT VARIABLE 
     207                        return new OSQLFilterItemVariable(iCommand, iWord); 
    201208 
    202209                // PARSE AS FIELD 
     
    223230 
    224231                if (iObject instanceof OSQLFilterItem) 
    225                         return ((OSQLFilterItem) iObject).getValue(null); 
     232                        return ((OSQLFilterItem) iObject).getValue(null, null); 
    226233 
    227234                return iObject; 
     
    233240 
    234241                if (iObject instanceof OSQLFilterItem) 
    235                         return ((OSQLFilterItem) iObject).getValue(iRecord); 
     242                        return ((OSQLFilterItem) iObject).getValue(iRecord, null); 
    236243 
    237244                return iObject; 
     
    245252                        if (field.getValue() instanceof OSQLFilterItemField) { 
    246253                                final OSQLFilterItemField f = (OSQLFilterItemField) field.getValue(); 
    247                                 if (f.getRoot().equals("?")) 
     254                                if (f.getRoot().equals("?")) { 
    248255                                        // POSITIONAL PARAMETER 
    249256                                        iDocument.field(field.getKey(), iArgs.get(paramCounter++)); 
    250                                 else if (f.getRoot().startsWith(":")) 
     257                                        continue; 
     258                                } else if (f.getRoot().startsWith(":")) { 
    251259                                        // NAMED PARAMETER 
    252260                                        iDocument.field(field.getKey(), iArgs.get(f.getRoot().substring(1))); 
    253                         } else 
    254                                 iDocument.field(field.getKey(), OSQLHelper.getValue(field.getValue(), iDocument)); 
     261                                        continue; 
     262                                } 
     263                        } 
     264 
     265                        iDocument.field(field.getKey(), OSQLHelper.getValue(field.getValue(), iDocument)); 
    255266                } 
    256267 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/filter/OSQLFilter.java

    r19431 r19635  
    2626 
    2727import com.orientechnologies.common.parser.OStringParser; 
     28import com.orientechnologies.orient.core.command.OCommandContext; 
    2829import com.orientechnologies.orient.core.command.OCommandToParse; 
    2930import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal; 
    3031import com.orientechnologies.orient.core.db.record.ODatabaseRecord; 
     32import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    3133import com.orientechnologies.orient.core.exception.OCommandExecutionException; 
    3234import com.orientechnologies.orient.core.exception.OQueryParsingException; 
     35import com.orientechnologies.orient.core.id.ORecordId; 
    3336import com.orientechnologies.orient.core.metadata.schema.OClass; 
    3437import com.orientechnologies.orient.core.metadata.schema.OProperty; 
     
    4245import com.orientechnologies.orient.core.sql.operator.OQueryOperator; 
    4346import com.orientechnologies.orient.core.sql.operator.OQueryOperatorNot; 
     47import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery; 
    4448 
    4549/** 
     
    5054 */ 
    5155public class OSQLFilter extends OCommandToParse { 
    52         protected ODatabaseRecord                                                               database; 
    53         protected List<String>                                                                  targetRecords; 
    54         protected Map<String, String>                                           targetClusters; 
    55         protected Map<OClass, String>                                           targetClasses; 
    56         protected String                                                                                                targetIndex; 
    57         protected Set<OProperty>                                                                properties      = new HashSet<OProperty>(); 
    58         protected OSQLFilterCondition                                           rootCondition; 
    59         protected List<String>                                                                  recordTransformed; 
    60         protected List<OSQLFilterItemParameter> parameterItems; 
    61         protected int                                                                                                           braces; 
    62  
    63         public OSQLFilter(final String iText) { 
     56        protected ODatabaseRecord                                                                               database; 
     57        protected Iterable<? extends OIdentifiable>     targetRecords; 
     58        protected Map<String, String>                                                           targetClusters; 
     59        protected Map<OClass, String>                                                           targetClasses; 
     60        protected String                                                                                                                targetIndex; 
     61        protected Set<OProperty>                                                                                properties      = new HashSet<OProperty>(); 
     62        protected OSQLFilterCondition                                                           rootCondition; 
     63        protected List<String>                                                                                  recordTransformed; 
     64        protected List<OSQLFilterItemParameter>                 parameterItems; 
     65        protected int                                                                                                                           braces; 
     66        private OCommandContext                                                                                 context; 
     67 
     68        public OSQLFilter(final String iText, final OCommandContext iContext) { 
     69                context = iContext; 
    6470                try { 
    6571                        database = ODatabaseRecordThreadLocal.INSTANCE.get(); 
     
    9197        } 
    9298 
    93         public boolean evaluate(final ORecord<?> iRecord) { 
     99        public boolean evaluate(final ORecord<?> iRecord, final OCommandContext iContext) { 
    94100                if (targetClasses != null) { 
    95101                        final OClass cls = targetClasses.keySet().iterator().next(); 
     
    104110                        return true; 
    105111 
    106                 return (Boolean) rootCondition.evaluate((ORecordSchemaAware<?>) iRecord); 
     112                return (Boolean) rootCondition.evaluate((ORecordSchemaAware<?>) iRecord, iContext); 
    107113        } 
    108114 
     
    112118                if (currentPos == -1) 
    113119                        throw new OQueryParsingException("No query target found", text, 0); 
    114  
    115                 targetRecords = new ArrayList<String>(); 
    116120 
    117121                final char c = text.charAt(currentPos); 
     
    122126                        currentPos = OSQLHelper.nextWord(text, textUpperCase, currentPos, word, true); 
    123127 
    124                         targetRecords.add(word.toString()); 
    125  
     128                        targetRecords = new ArrayList<OIdentifiable>(); 
     129                        ((List<OIdentifiable>) targetRecords).add(new ORecordId(word.toString())); 
     130 
     131                } else if (c == '(') { 
     132                        // SUB QUERY 
     133                        final StringBuilder sub = new StringBuilder(); 
     134                        currentPos = OStringSerializerHelper.getEmbedded(text, currentPos, -1, sub); 
     135                        targetRecords = new OSQLSynchQuery(sub.toString()); 
    126136                } else if (c == OStringSerializerHelper.COLLECTION_BEGIN) { 
    127137                        // COLLECTION OF RIDS 
    128                         currentPos = OStringSerializerHelper.getCollection(text, currentPos, targetRecords); 
     138                        final List<String> rids = new ArrayList<String>(); 
     139                        currentPos = OStringSerializerHelper.getCollection(text, currentPos, rids); 
     140 
     141                        targetRecords = new ArrayList<OIdentifiable>(); 
     142                        for (String rid : rids) 
     143                                ((List<OIdentifiable>) targetRecords).add(new ORecordId(rid)); 
     144 
    129145                        if (currentPos > -1) 
    130146                                currentPos++; 
     
    287303                                if (!jumpWhiteSpaces() || text.charAt(currentPos) == ')') 
    288304                                        braces--; 
    289                                 currentPos++; 
     305 
     306                                if (currentPos > -1) 
     307                                        currentPos++; 
    290308 
    291309                                result[i] = subCondition; 
     
    340358                                } 
    341359 
    342                                 result[i] = OSQLHelper.parseValue(this, this, words[1]); 
     360                                if (words[1].endsWith(")")) { 
     361                                        final int openParenthesis = words[1].indexOf('('); 
     362                                        if (openParenthesis == -1) 
     363                                                words[1] = words[1].substring(0, words[1].length() - 1); 
     364                                } 
     365 
     366                                result[i] = OSQLHelper.parseValue(this, this, words[1], context); 
    343367                        } 
    344368                } 
     
    350374                List<Object> coll = new ArrayList<Object>(); 
    351375                for (String s : stringItems) { 
    352                         coll.add(OSQLHelper.parseValue(this, this, s)); 
     376                        coll.add(OSQLHelper.parseValue(this, this, s, context)); 
    353377                } 
    354378                return coll; 
     
    363387        } 
    364388 
    365         public List<String> getTargetRecords() { 
     389        public Iterable<? extends OIdentifiable> getTargetRecords() { 
    366390                return targetRecords; 
    367391        } 
     
    428452                        } else if (c == ' ' && openBraces == 0) { 
    429453                                break; 
    430                         } else if (!Character.isLetter(c) && !Character.isDigit(c) && c != '.' && c != ':' && c != '-' && c != '_' && c != '+' 
    431                                         && c != '@' && openBraces == 0 && openBraket == 0) { 
     454                        } else if (!Character.isLetter(c) && !Character.isDigit(c) && c != '.' && c != '$' && c != ':' && c != '-' && c != '_' 
     455                                        && c != '+' && c != '@' && openBraces == 0 && openBraket == 0) { 
    432456                                if (iAdvanceWhenNotFound) 
    433457                                        currentPos++; 
     
    470494                        return; 
    471495 
    472                 if (iArgs.size() < parameterItems.size()) 
    473                         throw new OCommandExecutionException("Cannot execute because " + (parameterItems.size() - iArgs.size()) 
    474                                         + " parameter(s) are unbounded"); 
    475  
    476                 String paramName; 
    477496                for (Entry<Object, Object> entry : iArgs.entrySet()) { 
    478497                        if (entry.getKey() instanceof Integer) 
    479498                                parameterItems.get(((Integer) entry.getKey())).setValue(entry.setValue(entry.getValue())); 
    480499                        else { 
    481                                 paramName = entry.getKey().toString(); 
     500                                String paramName = entry.getKey().toString(); 
    482501                                for (OSQLFilterItemParameter value : parameterItems) { 
    483502                                        if (value.getName().equalsIgnoreCase(paramName)) { 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/filter/OSQLFilterCondition.java

    r19431 r19635  
    2525 
    2626import com.orientechnologies.common.collection.OMultiValue; 
     27import com.orientechnologies.orient.core.command.OCommandContext; 
    2728import com.orientechnologies.orient.core.config.OStorageConfiguration; 
     29import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal; 
     30import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2831import com.orientechnologies.orient.core.db.record.ORecordElement; 
    2932import com.orientechnologies.orient.core.exception.OQueryParsingException; 
     
    3235import com.orientechnologies.orient.core.id.ORecordId; 
    3336import com.orientechnologies.orient.core.query.OQueryRuntimeValueMulti; 
    34 import com.orientechnologies.orient.core.record.ORecordSchemaAware; 
    3537import com.orientechnologies.orient.core.serialization.serializer.OStringSerializerHelper; 
    3638import com.orientechnologies.orient.core.sql.OSQLHelper; 
     
    6163        } 
    6264 
    63         public Object evaluate(final ORecordSchemaAware<?> iRecord) { 
    64                 Object l = evaluate(iRecord, left); 
    65                 Object r = evaluate(iRecord, right); 
    66  
    67                 final Object[] convertedValues = checkForConversion(iRecord, l, r); 
     65        public Object evaluate(final OIdentifiable o, final OCommandContext iContext) { 
     66                Object l = evaluate(o, left, iContext); 
     67                Object r = evaluate(o, right, iContext); 
     68 
     69                final Object[] convertedValues = checkForConversion(o, l, r); 
    6870                if (convertedValues != null) { 
    6971                        l = convertedValues[0]; 
     
    8082                } 
    8183 
    82                 return operator.evaluateRecord(iRecord, this, l, r); 
     84                return operator.evaluateRecord(o, this, l, r, iContext); 
    8385        } 
    8486 
     
    103105        } 
    104106 
    105         private Object[] checkForConversion(final ORecordSchemaAware<?> iRecord, final Object l, final Object r) { 
     107        private Object[] checkForConversion(final OIdentifiable o, final Object l, final Object r) { 
    106108                Object[] result = null; 
    107109 
     
    139141                        // DATES 
    140142                        else if (r instanceof Date && !(l instanceof Collection || l instanceof Date)) { 
    141                                 result = new Object[] { getDate(iRecord, l), r }; 
     143                                result = new Object[] { getDate(l), r }; 
    142144                        } else if (l instanceof Date && !(r instanceof Collection || r instanceof Date)) { 
    143                                 result = new Object[] { l, getDate(iRecord, r) }; 
     145                                result = new Object[] { l, getDate(r) }; 
    144146                        } 
    145147 
     
    183185        } 
    184186 
    185         protected Date getDate(final ORecordSchemaAware<?> iRecord, final Object iValue) { 
     187        protected Date getDate(final Object iValue) { 
    186188                if (iValue == null) 
    187189                        return null; 
     
    202204                } 
    203205 
    204                 final OStorageConfiguration config = iRecord.getDatabase().getStorage().getConfiguration(); 
     206                final OStorageConfiguration config = ODatabaseRecordThreadLocal.INSTANCE.get().getStorage().getConfiguration(); 
    205207 
    206208                SimpleDateFormat formatter = config.getDateFormatInstance(); 
     
    219221        } 
    220222 
    221         protected Object evaluate(ORecordSchemaAware<?> iRecord, final Object iValue) { 
    222                 if (iRecord.getInternalStatus() == ORecordElement.STATUS.NOT_LOADED) { 
     223        protected Object evaluate(OIdentifiable o, final Object iValue, final OCommandContext iContext) { 
     224                if (o.getRecord().getInternalStatus() == ORecordElement.STATUS.NOT_LOADED) { 
    223225                        try { 
    224                                 iRecord = (ORecordSchemaAware<?>) iRecord.load(); 
     226                                o = o.getRecord().load(); 
    225227                        } catch (ORecordNotFoundException e) { 
    226228                                return null; 
     
    228230                } 
    229231 
    230                 if (iValue instanceof OSQLFilterItem) { 
    231                         return ((OSQLFilterItem) iValue).getValue(iRecord); 
    232                 } 
     232                if (iValue instanceof OSQLFilterItem) 
     233                        return ((OSQLFilterItem) iValue).getValue(o, iContext); 
    233234 
    234235                if (iValue instanceof OSQLFilterCondition) 
    235236                        // NESTED CONDITION: EVALUATE IT RECURSIVELY 
    236                         return ((OSQLFilterCondition) iValue).evaluate(iRecord); 
     237                        return ((OSQLFilterCondition) iValue).evaluate(o, iContext); 
    237238 
    238239                if (iValue instanceof OSQLFunctionRuntime) { 
    239240                        // STATELESS FUNCTION: EXECUTE IT 
    240241                        final OSQLFunctionRuntime f = (OSQLFunctionRuntime) iValue; 
    241                         return f.execute(iRecord, null); 
     242                        return f.execute(o, null); 
    242243                } 
    243244 
     
    250251                        for (final Object value : multiValue) { 
    251252                                if (value instanceof OSQLFilterItem) 
    252                                         result.add(((OSQLFilterItem) value).getValue(iRecord)); 
     253                                        result.add(((OSQLFilterItem) value).getValue(o, null)); 
    253254                                else 
    254255                                        result.add(value); 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/filter/OSQLFilterItem.java

    r18649 r19635  
    1616package com.orientechnologies.orient.core.sql.filter; 
    1717 
     18import com.orientechnologies.orient.core.command.OCommandContext; 
    1819import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1920 
     
    2627public interface OSQLFilterItem { 
    2728 
    28         public Object getValue(OIdentifiable iRecord); 
     29        public Object getValue(OIdentifiable iRecord, OCommandContext iContetx); 
    2930 
    3031} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/filter/OSQLFilterItemAbstract.java

    r19431 r19635  
    3434import com.orientechnologies.orient.core.exception.OQueryParsingException; 
    3535import com.orientechnologies.orient.core.exception.ORecordNotFoundException; 
    36 import com.orientechnologies.orient.core.id.ORID; 
    3736import com.orientechnologies.orient.core.id.ORecordId; 
    3837import com.orientechnologies.orient.core.record.ORecord; 
     
    126125 
    127126                                        else if (operator == OSQLFilterFieldOperator.TOUPPERCASE.id) 
    128                                                 ioResult = ioResult != null ? ioResult.toString().toUpperCase() : 0; 
     127                                                ioResult = ioResult != null ? ioResult.toString().toUpperCase() : null; 
    129128 
    130129                                        else if (operator == OSQLFilterFieldOperator.TOLOWERCASE.id) 
    131                                                 ioResult = ioResult != null ? ioResult.toString().toLowerCase() : 0; 
     130                                                ioResult = ioResult != null ? ioResult.toString().toLowerCase() : null; 
    132131 
    133132                                        else if (operator == OSQLFilterFieldOperator.TRIM.id) 
     
    139138                                                        if (ioResult instanceof String) { 
    140139                                                                try { 
    141                                                                         ioResult = new ODocument(ODatabaseRecordThreadLocal.INSTANCE.get(), new ORecordId((String) ioResult)); 
     140                                                                        ioResult = new ODocument(new ORecordId((String) ioResult)); 
    142141                                                                } catch (Exception e) { 
    143142                                                                        OLogManager.instance().error(this, "Error on reading rid with value '%s'", null, ioResult); 
    144143                                                                        ioResult = null; 
    145144                                                                } 
    146                                                         } else if (ioResult instanceof ORID) 
    147                                                                 ioResult = new ODocument(ODatabaseRecordThreadLocal.INSTANCE.get(), (ORID) ioResult); 
    148                                                         else if (ioResult instanceof ORecord<?>) 
    149                                                                 ioResult = (ODocument) ioResult; 
     145                                                        } else if (ioResult instanceof OIdentifiable) 
     146                                                                ioResult = ((OIdentifiable) ioResult).getRecord(); 
    150147 
    151148                                                        if (ioResult != null) { 
     
    289286                                buffer.append('.'); 
    290287                                buffer.append(OSQLFilterFieldOperator.getById(op.getKey())); 
    291                                 buffer.append(op.getValue()); 
     288                                if (op.getValue() != null) 
     289                                        buffer.append(op.getValue()); 
    292290                        } 
    293291                } 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/filter/OSQLFilterItemField.java

    r19431 r19635  
    1616package com.orientechnologies.orient.core.sql.filter; 
    1717 
     18import java.util.List; 
     19 
    1820import com.orientechnologies.common.util.OPair; 
     21import com.orientechnologies.orient.core.command.OCommandContext; 
    1922import com.orientechnologies.orient.core.command.OCommandToParse; 
    2023import com.orientechnologies.orient.core.db.record.OIdentifiable; 
     
    2225import com.orientechnologies.orient.core.record.impl.ODocument; 
    2326import com.orientechnologies.orient.core.record.impl.ODocumentHelper; 
    24  
    25 import java.util.List; 
    2627 
    2728/** 
     
    3839        } 
    3940 
    40         public Object getValue(final OIdentifiable iRecord) { 
     41        public Object getValue(final OIdentifiable iRecord, OCommandContext iContetx) { 
    4142                if (iRecord == null) 
    4243                        throw new OCommandExecutionException("expression item '" + name + "' cannot be resolved"); 
     
    5354        } 
    5455 
    55     /** 
    56      * Check whether or not this filter item is chain of fields (e.g. "field1.field2.field3"). 
    57      * Return true if filter item contains only field projections operators, if field item 
    58      * contains any other projection operator the method returns false. 
    59      * When filter item does not contains any chain operator, it is also field chain consist of one field. 
    60     * @return whether or not this filter item can be represented as chain of fields. 
    61     */ 
    62     public boolean isFieldChain() { 
    63         if (operationsChain == null) { 
    64             return true; 
    65         } 
     56        /** 
     57         * Check whether or not this filter item is chain of fields (e.g. "field1.field2.field3"). Return true if filter item contains 
     58         * only field projections operators, if field item contains any other projection operator the method returns false. When filter 
     59         * item does not contains any chain operator, it is also field chain consist of one field. 
     60         *  
     61        * @return whether or not this filter item can be represented as chain of fields. 
     62        */ 
     63        public boolean isFieldChain() { 
     64                if (operationsChain == null) { 
     65                        return true; 
     66                } 
    6667 
    67         for (OPair<Integer, List<String>> pair : operationsChain) { 
    68             if (!pair.getKey().equals(OSQLFilterFieldOperator.FIELD.id)) { 
    69                 return false; 
    70             } 
    71         } 
     68                for (OPair<Integer, List<String>> pair : operationsChain) { 
     69                        if (!pair.getKey().equals(OSQLFilterFieldOperator.FIELD.id)) { 
     70                                return false; 
     71                        } 
     72                } 
    7273 
    73         return true; 
    74     } 
     74                return true; 
     75        } 
    7576 
    76     /** 
    77      * Creates {@code FieldChain} in case when filter item can have such representation. 
    78      * 
    79      * @return {@code FieldChain} representation of this filter item. 
    80      * @throws IllegalStateException if this filter item can't be represented as {@code FieldChain}. 
    81      */ 
    82     public FieldChain getFieldChain() { 
    83         if (!isFieldChain()) { 
    84             throw new IllegalStateException("Filter item field contains not only field operators"); 
    85         } 
     77        /** 
     78         * Creates {@code FieldChain} in case when filter item can have such representation. 
     79         *  
     80         * @return {@code FieldChain} representation of this filter item. 
     81         * @throws IllegalStateException 
     82         *           if this filter item can't be represented as {@code FieldChain}. 
     83         */ 
     84        public FieldChain getFieldChain() { 
     85                if (!isFieldChain()) { 
     86                        throw new IllegalStateException("Filter item field contains not only field operators"); 
     87                } 
    8688 
    87         return new FieldChain(); 
    88     } 
     89                return new FieldChain(); 
     90        } 
    8991 
    90     /** 
    91      * Represents filter item as chain of fields. 
    92      * Provide interface to work with this chain like with sequence of field names. 
    93      */ 
    94     public class FieldChain { 
    95         private FieldChain() { 
    96         } 
     92        /** 
     93         * Represents filter item as chain of fields. Provide interface to work with this chain like with sequence of field names. 
     94         */ 
     95        public class FieldChain { 
     96                private FieldChain() { 
     97                } 
    9798 
    98         public String getItemName(int fieldIndex) { 
    99             if (fieldIndex == 0) { 
    100                 return name; 
    101             } else { 
    102                 return operationsChain.get(fieldIndex - 1).getValue().get(0); 
    103             } 
    104         } 
     99                public String getItemName(int fieldIndex) { 
     100                        if (fieldIndex == 0) { 
     101                                return name; 
     102                        } else { 
     103                                return operationsChain.get(fieldIndex - 1).getValue().get(0); 
     104                        } 
     105                } 
    105106 
    106         public int getItemCount() { 
    107             if (operationsChain == null) { 
    108                 return 1; 
    109             } else { 
    110                 return operationsChain.size() + 1; 
    111             } 
    112         } 
     107                public int getItemCount() { 
     108                        if (operationsChain == null) { 
     109                                return 1; 
     110                        } else { 
     111                                return operationsChain.size() + 1; 
     112                        } 
     113                } 
    113114 
    114         /** 
    115         * Field chain is considered as long chain if it contains more than one item. 
    116          * 
    117         * @return true if this chain is long and false in another case. 
    118         */ 
    119         public boolean isLong() { 
    120             return operationsChain != null && operationsChain.size() > 0; 
    121         } 
    122     } 
     115                /** 
     116                * Field chain is considered as long chain if it contains more than one item. 
     117                 *  
     118                * @return true if this chain is long and false in another case. 
     119                */ 
     120                public boolean isLong() { 
     121                        return operationsChain != null && operationsChain.size() > 0; 
     122                } 
     123        } 
    123124} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/filter/OSQLFilterItemFieldMultiAbstract.java

    r19245 r19635  
    1818import java.util.List; 
    1919 
     20import com.orientechnologies.orient.core.command.OCommandContext; 
    2021import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2122import com.orientechnologies.orient.core.query.OQueryRuntimeValueMulti; 
     
    3738        } 
    3839 
    39         public Object getValue(final OIdentifiable iRecord) { 
     40        public Object getValue(final OIdentifiable iRecord, OCommandContext iContetx) { 
    4041                if (names.size() == 1) 
    4142                        return transformValue(iRecord, ODocumentHelper.getIdentifiableValue(iRecord, names.get(0))); 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/filter/OSQLFilterItemParameter.java

    r18649 r19635  
    1616package com.orientechnologies.orient.core.sql.filter; 
    1717 
     18import com.orientechnologies.orient.core.command.OCommandContext; 
    1819import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1920 
     
    3435        } 
    3536 
    36         public Object getValue(final OIdentifiable iRecord) { 
     37        public Object getValue(final OIdentifiable iRecord, OCommandContext iContetx) { 
    3738                return value; 
    3839        } 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/functions/OSQLFunction.java

    r19015 r19635  
    1717 
    1818import com.orientechnologies.orient.core.command.OCommandExecutor; 
    19 import com.orientechnologies.orient.core.record.ORecord; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2020 
    2121/** 
     
    3030public interface OSQLFunction { 
    3131 
    32         public Object execute(ORecord<?> iCurrentRecord, Object[] iFuncParams, OCommandExecutor iRequester); 
     32        public Object execute(OIdentifiable o, Object[] iFuncParams, OCommandExecutor iRequester); 
    3333 
    3434        public boolean aggregateResults(Object[] configuredParameters); 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/functions/OSQLFunctionRuntime.java

    r19245 r19635  
    1818import java.util.List; 
    1919 
     20import com.orientechnologies.orient.core.command.OCommandContext; 
    2021import com.orientechnologies.orient.core.command.OCommandExecutor; 
    2122import com.orientechnologies.orient.core.command.OCommandToParse; 
     
    5657         * Execute a function. 
    5758         *  
    58          * @param iRecord 
     59         * @param o 
    5960         *          Current record 
    6061         * @param iRequester 
    6162         * @return 
    6263         */ 
    63         public Object execute(final ORecordSchemaAware<?> iRecord, final OCommandExecutor iRequester) { 
     64        public Object execute(final OIdentifiable o, final OCommandExecutor iRequester) { 
    6465                // RESOLVE VALUES USING THE CURRENT RECORD 
    6566                for (int i = 0; i < configuredParameters.length; ++i) { 
    6667                        if (configuredParameters[i] instanceof OSQLFilterItemField) 
    67                                 runtimeParameters[i] = ((OSQLFilterItemField) configuredParameters[i]).getValue(iRecord); 
     68                                runtimeParameters[i] = ((OSQLFilterItemField) configuredParameters[i]).getValue(o, null); 
    6869                        else if (configuredParameters[i] instanceof OSQLFunctionRuntime) 
    69                                 runtimeParameters[i] = ((OSQLFunctionRuntime) configuredParameters[i]).execute(iRecord, iRequester); 
     70                                runtimeParameters[i] = ((OSQLFunctionRuntime) configuredParameters[i]).execute(o, iRequester); 
    7071                } 
    7172 
    72                 final Object functionResult = function.execute(iRecord, runtimeParameters, iRequester); 
     73                final Object functionResult = function.execute(o, runtimeParameters, iRequester); 
    7374 
    74                 return transformValue(iRecord, functionResult); 
     75                return transformValue(o, functionResult); 
    7576        } 
    7677 
     
    8384        } 
    8485 
    85         public Object getValue(final OIdentifiable iRecord) { 
     86        public Object getValue(final OIdentifiable iRecord, OCommandContext iContetx) { 
    8687                return execute(iRecord != null ? (ORecordSchemaAware<?>) iRecord.getRecord() : null, null); 
    8788        } 
     
    116117                this.configuredParameters = new Object[funcParamsText.size()]; 
    117118                for (int i = 0; i < funcParamsText.size(); ++i) { 
    118                         this.configuredParameters[i] = OSQLHelper.parseValue(null, iQueryToParse, funcParamsText.get(i)); 
     119                        this.configuredParameters[i] = OSQLHelper.parseValue(null, iQueryToParse, funcParamsText.get(i), null); 
    119120                } 
    120121 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/functions/coll/OSQLFunctionDifference.java

    r19015 r19635  
    2020 
    2121import com.orientechnologies.orient.core.command.OCommandExecutor; 
    22 import com.orientechnologies.orient.core.record.ORecord; 
     22import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2323 
    2424/** 
     
    3636        } 
    3737 
    38         public Object execute(ORecord<?> iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
     38        public Object execute(OIdentifiable iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
    3939                if (iParameters[0] == null) 
    4040                        return null; 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/functions/coll/OSQLFunctionDistinct.java

    r19015 r19635  
    2020 
    2121import com.orientechnologies.orient.core.command.OCommandExecutor; 
    22 import com.orientechnologies.orient.core.record.ORecord; 
     22import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2323import com.orientechnologies.orient.core.sql.functions.OSQLFunctionAbstract; 
    2424 
     
    3838        } 
    3939 
    40         public Object execute(ORecord<?> iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
     40        public Object execute(final OIdentifiable iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
    4141                final Object value = iParameters[0]; 
    4242 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/functions/coll/OSQLFunctionIntersect.java

    r19015 r19635  
    2020 
    2121import com.orientechnologies.orient.core.command.OCommandExecutor; 
    22 import com.orientechnologies.orient.core.record.ORecord; 
     22import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2323 
    2424/** 
     
    3636        } 
    3737 
    38         public Object execute(ORecord<?> iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
     38        public Object execute(final OIdentifiable iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
    3939                Object value = iParameters[0]; 
    4040 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/functions/coll/OSQLFunctionUnion.java

    r19015 r19635  
    2020 
    2121import com.orientechnologies.orient.core.command.OCommandExecutor; 
    22 import com.orientechnologies.orient.core.record.ORecord; 
     22import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2323 
    2424/** 
     
    3636        } 
    3737 
    38         public Object execute(ORecord<?> iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
     38        public Object execute(final OIdentifiable iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
    3939                if (iParameters.length == 1) { 
    4040                        // AGGREGATION MODE (STATEFULL) 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/functions/geo/OSQLFunctionDistance.java

    r19015 r19635  
    1717 
    1818import com.orientechnologies.orient.core.command.OCommandExecutor; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1920import com.orientechnologies.orient.core.metadata.schema.OType; 
    20 import com.orientechnologies.orient.core.record.ORecord; 
    2121import com.orientechnologies.orient.core.sql.functions.OSQLFunctionAbstract; 
    2222 
     
    3636        } 
    3737 
    38         public Object execute(ORecord<?> iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
     38        public Object execute(final OIdentifiable iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
    3939                try { 
    4040                        double distance; 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/functions/math/OSQLFunctionAverage.java

    r19015 r19635  
    1717 
    1818import com.orientechnologies.orient.core.command.OCommandExecutor; 
    19 import com.orientechnologies.orient.core.record.ORecord; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2020 
    2121/** 
     
    3636        } 
    3737 
    38         public Object execute(ORecord<?> iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
     38        public Object execute(OIdentifiable iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
    3939                Number value = (Number) iParameters[0]; 
    4040 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/functions/math/OSQLFunctionMax.java

    r19015 r19635  
    1717 
    1818import com.orientechnologies.orient.core.command.OCommandExecutor; 
    19 import com.orientechnologies.orient.core.record.ORecord; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2020 
    2121/** 
     
    3636 
    3737        @SuppressWarnings("unchecked") 
    38         public Object execute(ORecord<?> iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
     38        public Object execute(final OIdentifiable iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
    3939                if (iParameters[0] == null || !(iParameters[0] instanceof Comparable<?>)) 
    4040                        // PRECONDITIONS 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/functions/math/OSQLFunctionMin.java

    r19015 r19635  
    1717 
    1818import com.orientechnologies.orient.core.command.OCommandExecutor; 
    19 import com.orientechnologies.orient.core.record.ORecord; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2020 
    2121/** 
     
    3636 
    3737        @SuppressWarnings("unchecked") 
    38         public Object execute(ORecord<?> iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
     38        public Object execute(final OIdentifiable iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
    3939                if (iParameters[0] == null || !(iParameters[0] instanceof Comparable<?>)) 
    4040                        // PRECONDITIONS 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/functions/math/OSQLFunctionSum.java

    r19015 r19635  
    1717 
    1818import com.orientechnologies.orient.core.command.OCommandExecutor; 
    19 import com.orientechnologies.orient.core.record.ORecord; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2020 
    2121/** 
     
    3535        } 
    3636 
    37         public Object execute(ORecord<?> iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
     37        public Object execute(final OIdentifiable iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
    3838                Number value = (Number) iParameters[0]; 
    3939 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/functions/misc/OSQLFunctionCount.java

    r19015 r19635  
    1717 
    1818import com.orientechnologies.orient.core.command.OCommandExecutor; 
    19 import com.orientechnologies.orient.core.record.ORecord; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2020import com.orientechnologies.orient.core.sql.functions.math.OSQLFunctionMathAbstract; 
    2121 
     
    3636        } 
    3737 
    38         public Object execute(ORecord<?> iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
     38        public Object execute(OIdentifiable iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
    3939                if (iParameters[0] != null) 
    4040                        total++; 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/functions/misc/OSQLFunctionDate.java

    r19245 r19635  
    2121 
    2222import com.orientechnologies.orient.core.command.OCommandExecutor; 
     23import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2324import com.orientechnologies.orient.core.exception.OQueryParsingException; 
    24 import com.orientechnologies.orient.core.record.ORecord; 
    2525import com.orientechnologies.orient.core.sql.OCommandSQLParsingException; 
    2626import com.orientechnologies.orient.core.sql.functions.OSQLFunctionAbstract; 
     
    4747        } 
    4848 
    49         public Object execute(ORecord<?> iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
     49        public Object execute(OIdentifiable iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
    5050                if (iParameters.length == 0) 
    5151                        return date; 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/functions/misc/OSQLFunctionFormat.java

    r19015 r19635  
    1717 
    1818import com.orientechnologies.orient.core.command.OCommandExecutor; 
    19 import com.orientechnologies.orient.core.record.ORecord; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2020import com.orientechnologies.orient.core.sql.functions.OSQLFunctionAbstract; 
    2121 
     
    3333        } 
    3434 
    35         public Object execute(ORecord<?> iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
     35        public Object execute(OIdentifiable iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
    3636                final Object[] args = new Object[iParameters.length - 1]; 
    3737 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/functions/misc/OSQLFunctionSysdate.java

    r19245 r19635  
    2020 
    2121import com.orientechnologies.orient.core.command.OCommandExecutor; 
    22 import com.orientechnologies.orient.core.record.ORecord; 
     22import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2323import com.orientechnologies.orient.core.sql.functions.OSQLFunctionAbstract; 
    2424 
     
    4444        } 
    4545 
    46         public Object execute(ORecord<?> iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
     46        public Object execute(final OIdentifiable iCurrentRecord, final Object[] iParameters, OCommandExecutor iRequester) { 
    4747                if (iParameters.length == 0) 
    4848                        return now; 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperator.java

    r19431 r19635  
    1818import java.util.List; 
    1919 
     20import com.orientechnologies.orient.core.command.OCommandContext; 
     21import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2022import com.orientechnologies.orient.core.id.ORID; 
    21 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2223import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
    2324 
     
    4849        } 
    4950 
    50         public abstract Object evaluateRecord(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    51                         final Object iRight); 
     51        public abstract Object evaluateRecord(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     52                        final Object iRight, OCommandContext iContext); 
    5253 
    5354        public abstract OIndexReuseType getIndexReuseType(Object iLeft, Object iRight); 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorAnd.java

    r19431 r19635  
    1616package com.orientechnologies.orient.core.sql.operator; 
    1717 
     18import com.orientechnologies.orient.core.command.OCommandContext; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1820import com.orientechnologies.orient.core.id.ORID; 
    19 import com.orientechnologies.orient.core.record.ORecordInternal; 
    20 import com.orientechnologies.orient.core.record.impl.ODocumentHelper; 
    21 import com.orientechnologies.orient.core.sql.OSQLHelper; 
    2221import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
    23 import com.orientechnologies.orient.core.sql.filter.OSQLFilterItemField; 
    24  
    25 import java.util.List; 
    2622 
    2723/** 
     
    3834 
    3935        @Override 
    40         public Object evaluateRecord(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    41                         final Object iRight) { 
     36        public Object evaluateRecord(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     37                        final Object iRight, OCommandContext iContext) { 
    4238                if (iLeft == null) 
    4339                        return false; 
     
    5248        } 
    5349 
    54   @Override 
    55   public ORID getBeginRidRange(final Object iLeft, final Object iRight) { 
    56     final ORID leftRange; 
    57     final ORID rightRange; 
     50        @Override 
     51        public ORID getBeginRidRange(final Object iLeft, final Object iRight) { 
     52                final ORID leftRange; 
     53                final ORID rightRange; 
    5854 
    59     if(iLeft instanceof OSQLFilterCondition) 
    60       leftRange = ((OSQLFilterCondition) iLeft).getBeginRidRange(); 
    61     else 
    62       leftRange = null; 
     55                if (iLeft instanceof OSQLFilterCondition) 
     56                        leftRange = ((OSQLFilterCondition) iLeft).getBeginRidRange(); 
     57                else 
     58                        leftRange = null; 
    6359 
    64     if(iRight instanceof OSQLFilterCondition) 
    65       rightRange = ((OSQLFilterCondition) iRight).getBeginRidRange(); 
    66     else 
    67       rightRange = null; 
     60                if (iRight instanceof OSQLFilterCondition) 
     61                        rightRange = ((OSQLFilterCondition) iRight).getBeginRidRange(); 
     62                else 
     63                        rightRange = null; 
    6864 
    69     if(leftRange == null && rightRange == null) 
    70       return null; 
    71     else if(leftRange == null) 
    72       return rightRange; 
    73     else if(rightRange == null) 
    74       return leftRange; 
    75     else 
    76       return leftRange.compareTo(rightRange) <= 0 ? rightRange : leftRange; 
    77   } 
     65                if (leftRange == null && rightRange == null) 
     66                        return null; 
     67                else if (leftRange == null) 
     68                        return rightRange; 
     69                else if (rightRange == null) 
     70                        return leftRange; 
     71                else 
     72                        return leftRange.compareTo(rightRange) <= 0 ? rightRange : leftRange; 
     73        } 
    7874 
    79   @Override 
    80   public ORID getEndRidRange(final Object iLeft, final Object iRight) { 
    81     final ORID leftRange; 
    82     final ORID rightRange; 
     75        @Override 
     76        public ORID getEndRidRange(final Object iLeft, final Object iRight) { 
     77                final ORID leftRange; 
     78                final ORID rightRange; 
    8379 
    84     if(iLeft instanceof OSQLFilterCondition) 
    85       leftRange = ((OSQLFilterCondition) iLeft).getEndRidRange(); 
    86     else 
    87       leftRange = null; 
     80                if (iLeft instanceof OSQLFilterCondition) 
     81                        leftRange = ((OSQLFilterCondition) iLeft).getEndRidRange(); 
     82                else 
     83                        leftRange = null; 
    8884 
    89     if(iRight instanceof OSQLFilterCondition) 
    90       rightRange = ((OSQLFilterCondition) iRight).getEndRidRange(); 
    91     else 
    92       rightRange = null; 
     85                if (iRight instanceof OSQLFilterCondition) 
     86                        rightRange = ((OSQLFilterCondition) iRight).getEndRidRange(); 
     87                else 
     88                        rightRange = null; 
    9389 
    94     if(leftRange == null && rightRange == null) 
    95       return null; 
    96     else if(leftRange == null) 
    97       return rightRange; 
    98     else if(rightRange == null) 
    99       return leftRange; 
    100     else 
    101       return leftRange.compareTo(rightRange) >= 0 ? rightRange : leftRange; 
    102   } 
     90                if (leftRange == null && rightRange == null) 
     91                        return null; 
     92                else if (leftRange == null) 
     93                        return rightRange; 
     94                else if (rightRange == null) 
     95                        return leftRange; 
     96                else 
     97                        return leftRange.compareTo(rightRange) >= 0 ? rightRange : leftRange; 
     98        } 
    10399} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorBetween.java

    r19015 r19635  
    1919 
    2020import com.orientechnologies.common.collection.OMultiValue; 
     21import com.orientechnologies.orient.core.command.OCommandContext; 
     22import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2123import com.orientechnologies.orient.core.id.ORID; 
    2224import com.orientechnologies.orient.core.metadata.schema.OType; 
    23 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2425import com.orientechnologies.orient.core.record.impl.ODocumentHelper; 
    2526import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
     
    4041        @Override 
    4142        @SuppressWarnings("unchecked") 
    42         protected boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    43                         final Object iRight) { 
     43        protected boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     44                        final Object iRight, OCommandContext iContext) { 
    4445    validate(iRight); 
    4546 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorContains.java

    r19431 r19635  
    1616package com.orientechnologies.orient.core.sql.operator; 
    1717 
    18 import java.util.Collection; 
    19  
     18import com.orientechnologies.orient.core.command.OCommandContext; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2020import com.orientechnologies.orient.core.id.ORID; 
    21 import com.orientechnologies.orient.core.record.ORecordInternal; 
    22 import com.orientechnologies.orient.core.record.ORecordSchemaAware; 
    2321import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
    2422 
     
    3735        @Override 
    3836        @SuppressWarnings("unchecked") 
    39         protected boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    40                         final Object iRight) { 
     37        protected boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     38                        final Object iRight, OCommandContext iContext) { 
    4139                final OSQLFilterCondition condition; 
    4240                if (iCondition.getLeft() instanceof OSQLFilterCondition) 
     
    4745                        condition = null; 
    4846 
    49                 if (iLeft instanceof Collection<?>) { 
     47                if (iLeft instanceof Iterable<?>) { 
    5048 
    51                         final Collection<Object> collection = (Collection<Object>) iLeft; 
     49                        final Iterable<Object> iterable = (Iterable<Object>) iLeft; 
    5250 
    5351                        if (condition != null) { 
    5452                                // CHECK AGAINST A CONDITION 
    55                                 for (final Object o : collection) { 
    56                                         if ((Boolean) condition.evaluate((ORecordSchemaAware<?>) o) == Boolean.TRUE) 
     53                                for (final Object o : iterable) { 
     54                                        if ((Boolean) condition.evaluate((OIdentifiable) o, iContext) == Boolean.TRUE) 
    5755                                                return true; 
    5856                                } 
    5957                        } else { 
    6058                                // CHECK AGAINST A SINGLE VALUE 
    61                                 for (final Object o : collection) { 
     59                                for (final Object o : iterable) { 
    6260                                        if (OQueryOperatorEquals.equals(iRight, o)) 
    6361                                                return true; 
    6462                                } 
    6563                        } 
    66                 } else if (iRight instanceof Collection<?>) { 
     64                } else if (iRight instanceof Iterable<?>) { 
    6765 
    6866                        // CHECK AGAINST A CONDITION 
    69                         final Collection<ORecordSchemaAware<?>> collection = (Collection<ORecordSchemaAware<?>>) iRight; 
     67                        final Iterable<OIdentifiable> iterable = (Iterable<OIdentifiable>) iRight; 
    7068 
    7169                        if (condition != null) { 
    72                                 for (final ORecordSchemaAware<?> o : collection) { 
    73                                         if ((Boolean) condition.evaluate(o) == Boolean.TRUE) 
     70                                for (final OIdentifiable o : iterable) { 
     71                                        if ((Boolean) condition.evaluate(o, iContext) == Boolean.TRUE) 
    7472                                                return true; 
    7573                                } 
    7674                        } else { 
    7775                                // CHECK AGAINST A SINGLE VALUE 
    78                                 for (final Object o : collection) { 
     76                                for (final Object o : iterable) { 
    7977                                        if (OQueryOperatorEquals.equals(iLeft, o)) 
    8078                                                return true; 
     
    8785        @Override 
    8886        public OIndexReuseType getIndexReuseType(final Object iLeft, final Object iRight) { 
    89     if(!(iLeft instanceof OSQLFilterCondition) && !(iRight instanceof OSQLFilterCondition)) 
    90       return OIndexReuseType.INDEX_METHOD; 
     87                if (!(iLeft instanceof OSQLFilterCondition) && !(iRight instanceof OSQLFilterCondition)) 
     88                        return OIndexReuseType.INDEX_METHOD; 
    9189 
    9290                return OIndexReuseType.NO_INDEX; 
    9391        } 
    9492 
     93        @Override 
     94        public ORID getBeginRidRange(Object iLeft, Object iRight) { 
     95                return null; 
     96        } 
    9597 
    96   @Override 
    97   public ORID getBeginRidRange(Object iLeft, Object iRight) { 
    98     return null; 
    99   } 
    100  
    101   @Override 
    102   public ORID getEndRidRange(Object iLeft, Object iRight) { 
    103     return null; 
    104   } 
     98        @Override 
     99        public ORID getEndRidRange(Object iLeft, Object iRight) { 
     100                return null; 
     101        } 
    105102 
    106103} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorContainsAll.java

    r19015 r19635  
    1818import java.util.Collection; 
    1919 
     20import com.orientechnologies.orient.core.command.OCommandContext; 
     21import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2022import com.orientechnologies.orient.core.id.ORID; 
    21 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2223import com.orientechnologies.orient.core.record.ORecordSchemaAware; 
    2324import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
     
    3738        @Override 
    3839        @SuppressWarnings("unchecked") 
    39         protected boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    40                         final Object iRight) { 
     40        protected boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     41                        final Object iRight, OCommandContext iContext) { 
    4142                final OSQLFilterCondition condition; 
    4243 
     
    8283                                // CHECK AGAINST A CONDITION 
    8384                                for (final ORecordSchemaAware<?> o : collection) { 
    84                                         if ((Boolean) condition.evaluate(o) == Boolean.FALSE) 
     85                                        if ((Boolean) condition.evaluate(o, iContext) == Boolean.FALSE) 
    8586                                                return false; 
    8687                                } 
     
    99100                        if (condition != null) { 
    100101                                for (final ORecordSchemaAware<?> o : collection) { 
    101                                         if ((Boolean) condition.evaluate(o) == Boolean.FALSE) 
     102                                        if ((Boolean) condition.evaluate(o, iContext) == Boolean.FALSE) 
    102103                                                return false; 
    103104                                } 
     
    118119        } 
    119120 
     121        @Override 
     122        public ORID getBeginRidRange(Object iLeft, Object iRight) { 
     123                return null; 
     124        } 
    120125 
    121   @Override 
    122   public ORID getBeginRidRange(Object iLeft, Object iRight) { 
    123     return null; 
    124   } 
    125  
    126   @Override 
    127   public ORID getEndRidRange(Object iLeft, Object iRight) { 
    128     return null; 
    129   } 
     126        @Override 
     127        public ORID getEndRidRange(Object iLeft, Object iRight) { 
     128                return null; 
     129        } 
    130130} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorContainsKey.java

    r19431 r19635  
    1818import java.util.Map; 
    1919 
     20import com.orientechnologies.orient.core.command.OCommandContext; 
     21import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2022import com.orientechnologies.orient.core.id.ORID; 
    21 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2223import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
    2324 
     
    3637        @Override 
    3738        @SuppressWarnings("unchecked") 
    38         protected boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    39                         final Object iRight) { 
     39        protected boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     40                        final Object iRight, OCommandContext iContext) { 
    4041 
    4142                if (iLeft instanceof Map<?, ?>) { 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorContainsValue.java

    r19431 r19635  
    1919 
    2020import com.orientechnologies.common.exception.OException; 
     21import com.orientechnologies.orient.core.command.OCommandContext; 
     22import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2123import com.orientechnologies.orient.core.db.record.ORecordElement; 
    2224import com.orientechnologies.orient.core.exception.ORecordNotFoundException; 
    2325import com.orientechnologies.orient.core.id.ORID; 
    2426import com.orientechnologies.orient.core.record.ORecord; 
    25 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2627import com.orientechnologies.orient.core.record.ORecordSchemaAware; 
    2728import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
     
    4142        @Override 
    4243        @SuppressWarnings("unchecked") 
    43         protected boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    44                         final Object iRight) { 
     44        protected boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     45                        final Object iRight, OCommandContext iContext) { 
    4546                final OSQLFilterCondition condition; 
    4647                if (iCondition.getLeft() instanceof OSQLFilterCondition) 
     
    5758                                // CHECK AGAINST A CONDITION 
    5859                                for (Object o : map.values()) { 
    59                     o = loadIfNeed(o); 
    60                                         if ((Boolean) condition.evaluate((ORecordSchemaAware<?>) o)) 
     60                                        o = loadIfNeed(o); 
     61                                        if ((Boolean) condition.evaluate((ORecordSchemaAware<?>) o, iContext)) 
    6162                                                return true; 
    62                 } 
     63                                } 
    6364                        } else 
    6465                                return map.containsValue(iRight); 
     
    7071                                // CHECK AGAINST A CONDITION 
    7172                                for (Object o : map.values()) { 
    72                     o = loadIfNeed(o); 
    73                     if ((Boolean) condition.evaluate((ORecordSchemaAware<?>) o)) 
     73                                        o = loadIfNeed(o); 
     74                                        if ((Boolean) condition.evaluate((ORecordSchemaAware<?>) o, iContext)) 
    7475                                                return true; 
    7576                                        else 
    7677                                                return map.containsValue(iLeft); 
    77                 } 
     78                                } 
    7879                } 
    7980                return false; 
    8081        } 
    8182 
    82     private Object loadIfNeed(Object o) { 
    83         final ORecord<?> record = (ORecord) o; 
    84         if (record.getRecord().getInternalStatus() == ORecordElement.STATUS.NOT_LOADED) { 
    85             try { 
    86                 o = record.<ORecord>load(); 
    87             } catch (ORecordNotFoundException e) { 
    88                 throw new OException("Error during loading record with id : " + record.getIdentity()); 
    89             } 
    90         } 
    91         return o; 
    92     } 
     83        @SuppressWarnings("unchecked") 
     84        private Object loadIfNeed(Object o) { 
     85                final ORecord<?> record = (ORecord<?>) o; 
     86                if (record.getRecord().getInternalStatus() == ORecordElement.STATUS.NOT_LOADED) { 
     87                        try { 
     88                                o = record.<ORecord> load(); 
     89                        } catch (ORecordNotFoundException e) { 
     90                                throw new OException("Error during loading record with id : " + record.getIdentity()); 
     91                        } 
     92                } 
     93                return o; 
     94        } 
    9395 
    94     @Override 
     96        @Override 
    9597        public OIndexReuseType getIndexReuseType(final Object iLeft, final Object iRight) { 
    96     if(!(iRight instanceof OSQLFilterCondition) && !(iLeft instanceof OSQLFilterCondition)) 
    97       return OIndexReuseType.INDEX_METHOD; 
     98                if (!(iRight instanceof OSQLFilterCondition) && !(iLeft instanceof OSQLFilterCondition)) 
     99                        return OIndexReuseType.INDEX_METHOD; 
    98100 
    99101                return OIndexReuseType.NO_INDEX; 
    100102        } 
    101103 
    102   @Override 
    103   public ORID getBeginRidRange(Object iLeft, Object iRight) { 
    104     return null; 
    105   } 
     104        @Override 
     105        public ORID getBeginRidRange(Object iLeft, Object iRight) { 
     106                return null; 
     107        } 
    106108 
    107   @Override 
    108   public ORID getEndRidRange(Object iLeft, Object iRight) { 
    109     return null; 
    110   } 
     109        @Override 
     110        public ORID getEndRidRange(Object iLeft, Object iRight) { 
     111                return null; 
     112        } 
    111113} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorEquality.java

    r19431 r19635  
    1616package com.orientechnologies.orient.core.sql.operator; 
    1717 
     18import com.orientechnologies.orient.core.command.OCommandContext; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1820import com.orientechnologies.orient.core.query.OQueryRuntimeValueMulti; 
    19 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2021import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
    2122import com.orientechnologies.orient.core.sql.filter.OSQLFilterItemFieldAll; 
     
    3839        } 
    3940 
    40         protected abstract boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, 
    41                         final Object iLeft, final Object iRight); 
     41        protected abstract boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, 
     42                        final Object iLeft, final Object iRight, OCommandContext iContext); 
    4243 
    4344        @Override 
    44         public Object evaluateRecord(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    45                         final Object iRight) { 
     45        public Object evaluateRecord(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     46                        final Object iRight, OCommandContext iContext) { 
    4647                if (iLeft instanceof OQueryRuntimeValueMulti) { 
    4748                        // LEFT = MULTI 
     
    5455                                // ALL VALUES 
    5556                                for (final Object v : left.values) 
    56                                         if (v == null || !evaluateExpression(iRecord, iCondition, v, iRight)) 
     57                                        if (v == null || !evaluateExpression(iRecord, iCondition, v, iRight, iContext)) 
    5758                                                return false; 
    5859                                return true; 
     
    6061                                // ANY VALUES 
    6162                                for (final Object v : left.values) 
    62                                         if (v != null && evaluateExpression(iRecord, iCondition, v, iRight)) 
     63                                        if (v != null && evaluateExpression(iRecord, iCondition, v, iRight, iContext)) 
    6364                                                return true; 
    6465                                return false; 
     
    7576                                // ALL VALUES 
    7677                                for (final Object v : right.values) 
    77                                         if (v == null || !evaluateExpression(iRecord, iCondition, iLeft, v)) 
     78                                        if (v == null || !evaluateExpression(iRecord, iCondition, iLeft, v, iContext)) 
    7879                                                return false; 
    7980                                return true; 
     
    8182                                // ANY VALUES 
    8283                                for (final Object v : right.values) 
    83                                         if (v != null && evaluateExpression(iRecord, iCondition, iLeft, v)) 
     84                                        if (v != null && evaluateExpression(iRecord, iCondition, iLeft, v, iContext)) 
    8485                                                return true; 
    8586                                return false; 
     
    8788                } else 
    8889                        // SINGLE SIMPLE ITEM 
    89                         return evaluateExpression(iRecord, iCondition, iLeft, iRight); 
     90                        return evaluateExpression(iRecord, iCondition, iLeft, iRight, iContext); 
    9091        } 
    9192} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorEqualityNotNulls.java

    r17961 r19635  
    1616package com.orientechnologies.orient.core.sql.operator; 
    1717 
    18 import com.orientechnologies.orient.core.record.ORecordInternal; 
     18import com.orientechnologies.orient.core.command.OCommandContext; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1920import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
    2021 
     
    3738 
    3839        @Override 
    39         public Object evaluateRecord(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    40                         final Object iRight) { 
     40        public Object evaluateRecord(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     41                        final Object iRight, OCommandContext iContext) { 
    4142                if (iLeft == null || iRight == null) 
    4243                        return false; 
    4344 
    44                 return super.evaluateRecord(iRecord, iCondition, iLeft, iRight); 
     45                return super.evaluateRecord(iRecord, iCondition, iLeft, iRight, iContext); 
    4546        } 
    4647} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorEquals.java

    r19431 r19635  
    1616package com.orientechnologies.orient.core.sql.operator; 
    1717 
     18import com.orientechnologies.orient.core.command.OCommandContext; 
    1819import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1920import com.orientechnologies.orient.core.id.ORID; 
    2021import com.orientechnologies.orient.core.metadata.schema.OType; 
    2122import com.orientechnologies.orient.core.record.ORecord; 
    22 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2323import com.orientechnologies.orient.core.record.impl.ODocumentHelper; 
    2424import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
     
    3939 
    4040        @Override 
    41         protected boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    42                         final Object iRight) { 
     41        protected boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     42                        final Object iRight, OCommandContext iContext) { 
    4343                return equals(iLeft, iRight); 
    4444        } 
     
    7979      else { 
    8080        if (iRight instanceof OSQLFilterItemParameter && 
    81                 ((OSQLFilterItemParameter) iRight).getValue(null) instanceof ORID) 
    82           return (ORID) ((OSQLFilterItemParameter) iRight).getValue(null); 
     81                ((OSQLFilterItemParameter) iRight).getValue(null, null) instanceof ORID) 
     82          return (ORID) ((OSQLFilterItemParameter) iRight).getValue(null, null); 
    8383      } 
    8484 
     
    9090      else { 
    9191        if (iLeft instanceof OSQLFilterItemParameter && 
    92                 ((OSQLFilterItemParameter) iLeft).getValue(null) instanceof ORID) 
    93           return (ORID) ((OSQLFilterItemParameter) iLeft).getValue(null); 
     92                ((OSQLFilterItemParameter) iLeft).getValue(null, null) instanceof ORID) 
     93          return (ORID) ((OSQLFilterItemParameter) iLeft).getValue(null, null); 
    9494      } 
    9595 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorIn.java

    r19015 r19635  
    2222 
    2323import com.orientechnologies.common.collection.OMultiValue; 
     24import com.orientechnologies.orient.core.command.OCommandContext; 
     25import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2426import com.orientechnologies.orient.core.id.ORID; 
    25 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2627import com.orientechnologies.orient.core.record.impl.ODocumentHelper; 
    2728import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
     
    4445        @Override 
    4546        @SuppressWarnings("unchecked") 
    46         protected boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    47                         final Object iRight) { 
     47        protected boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     48                        final Object iRight, OCommandContext iContext) { 
    4849                if (iLeft instanceof Collection<?>) { 
    4950                        final Collection<Object> sourceCollection = (Collection<Object>) iLeft; 
     
    114115      if(rid instanceof ORID) 
    115116        rids.add((ORID)rid); 
    116       else if(rid instanceof OSQLFilterItemParameter && ((OSQLFilterItemParameter) rid).getValue(null) instanceof ORID) 
    117         rids.add((ORID)((OSQLFilterItemParameter) rid).getValue(null)); 
     117      else if(rid instanceof OSQLFilterItemParameter && ((OSQLFilterItemParameter) rid).getValue(null, null) instanceof ORID) 
     118        rids.add((ORID)((OSQLFilterItemParameter) rid).getValue(null, null)); 
    118119    } 
    119120 
     
    141142      if(rid instanceof ORID) 
    142143        rids.add((ORID)rid); 
    143       else if(rid instanceof OSQLFilterItemParameter && ((OSQLFilterItemParameter) rid).getValue(null) instanceof ORID) 
    144         rids.add((ORID)((OSQLFilterItemParameter) rid).getValue(null)); 
     144      else if(rid instanceof OSQLFilterItemParameter && ((OSQLFilterItemParameter) rid).getValue(null, null) instanceof ORID) 
     145        rids.add((ORID)((OSQLFilterItemParameter) rid).getValue(null, null)); 
    145146    } 
    146147 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorIs.java

    r19015 r19635  
    1616package com.orientechnologies.orient.core.sql.operator; 
    1717 
     18import com.orientechnologies.orient.core.command.OCommandContext; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1820import com.orientechnologies.orient.core.id.ORID; 
    19 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2021import com.orientechnologies.orient.core.record.impl.ODocument; 
    2122import com.orientechnologies.orient.core.sql.OSQLHelper; 
     
    3536 
    3637        @Override 
    37         protected boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    38                         final Object iRight) { 
     38        protected boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     39                        final Object iRight, OCommandContext iContext) { 
    3940                if (OSQLHelper.NOT_NULL.equals(iRight)) 
    4041                        return iLeft != null; 
     
    4950        } 
    5051 
    51         protected boolean evaluateDefined(final ORecordInternal<?> iRecord, final String iFieldName) { 
     52        protected boolean evaluateDefined(final OIdentifiable iRecord, final String iFieldName) { 
    5253                if (iRecord instanceof ODocument) { 
    5354                        return ((ODocument) iRecord).containsField(iFieldName); 
     
    6162        } 
    6263 
    63   @Override 
    64   public ORID getBeginRidRange(Object iLeft, Object iRight) { 
    65     return null; 
    66   } 
     64        @Override 
     65        public ORID getBeginRidRange(Object iLeft, Object iRight) { 
     66                return null; 
     67        } 
    6768 
    68   @Override 
    69   public ORID getEndRidRange(Object iLeft, Object iRight) { 
    70     return null; 
    71   } 
     69        @Override 
     70        public ORID getEndRidRange(Object iLeft, Object iRight) { 
     71                return null; 
     72        } 
    7273 
    7374} 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorLike.java

    r19015 r19635  
    1717 
    1818import com.orientechnologies.common.collection.OMultiValue; 
     19import com.orientechnologies.orient.core.command.OCommandContext; 
     20import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1921import com.orientechnologies.orient.core.id.ORID; 
    2022import com.orientechnologies.orient.core.query.OQueryHelper; 
    21 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2223import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
    2324 
     
    3536 
    3637        @Override 
    37         protected boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    38                         final Object iRight) { 
     38        protected boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     39                        final Object iRight, OCommandContext iContext) { 
    3940                if (OMultiValue.isMultiValue(iLeft) || OMultiValue.isMultiValue(iRight)) 
    4041                        return false; 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorMajor.java

    r19015 r19635  
    1616package com.orientechnologies.orient.core.sql.operator; 
    1717 
     18import com.orientechnologies.orient.core.command.OCommandContext; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1820import com.orientechnologies.orient.core.id.ORID; 
    1921import com.orientechnologies.orient.core.id.ORecordId; 
    2022import com.orientechnologies.orient.core.metadata.schema.OType; 
    21 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2223import com.orientechnologies.orient.core.record.impl.ODocumentHelper; 
    2324import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
     
    3940        @Override 
    4041        @SuppressWarnings("unchecked") 
    41         protected boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    42                         final Object iRight) { 
     42        protected boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     43                        final Object iRight, OCommandContext iContext) { 
    4344                final Object right = OType.convert(iRight, iLeft.getClass()); 
    4445                if (right == null) 
     
    6263      else { 
    6364        if (iRight instanceof OSQLFilterItemParameter && 
    64                 ((OSQLFilterItemParameter) iRight).getValue(null) instanceof ORID) 
    65           return new ORecordId(((ORID) ((OSQLFilterItemParameter) iRight).getValue(null)).next()); 
     65                ((OSQLFilterItemParameter) iRight).getValue(null, null) instanceof ORID) 
     66          return new ORecordId(((ORID) ((OSQLFilterItemParameter) iRight).getValue(null, null)).next()); 
    6667      } 
    6768    return null; 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorMajorEquals.java

    r19015 r19635  
    1616package com.orientechnologies.orient.core.sql.operator; 
    1717 
     18import com.orientechnologies.orient.core.command.OCommandContext; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1820import com.orientechnologies.orient.core.id.ORID; 
    1921import com.orientechnologies.orient.core.id.ORecordId; 
    2022import com.orientechnologies.orient.core.metadata.schema.OType; 
    21 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2223import com.orientechnologies.orient.core.record.impl.ODocumentHelper; 
    2324import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
     
    3940        @Override 
    4041        @SuppressWarnings("unchecked") 
    41         protected boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    42                         final Object iRight) { 
     42        protected boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     43                        final Object iRight, OCommandContext iContext) { 
    4344                final Object right = OType.convert(iRight, iLeft.getClass()); 
    4445                if (right == null) 
     
    6263    else { 
    6364      if (iRight instanceof OSQLFilterItemParameter && 
    64               ((OSQLFilterItemParameter) iRight).getValue(null) instanceof ORID) 
    65         return (ORID) ((OSQLFilterItemParameter) iRight).getValue(null); 
     65              ((OSQLFilterItemParameter) iRight).getValue(null, null) instanceof ORID) 
     66        return (ORID) ((OSQLFilterItemParameter) iRight).getValue(null, null); 
    6667    } 
    6768 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorMatches.java

    r19015 r19635  
    1616package com.orientechnologies.orient.core.sql.operator; 
    1717 
     18import com.orientechnologies.orient.core.command.OCommandContext; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1820import com.orientechnologies.orient.core.id.ORID; 
    19 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2021import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
    2122 
     
    3334 
    3435        @Override 
    35         protected boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    36                         final Object iRight) { 
     36        protected boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     37                        final Object iRight, OCommandContext iContext) { 
    3738                return iLeft.toString().matches((String) iRight); 
    3839        } 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorMinor.java

    r19015 r19635  
    1616package com.orientechnologies.orient.core.sql.operator; 
    1717 
     18import com.orientechnologies.orient.core.command.OCommandContext; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1820import com.orientechnologies.orient.core.id.ORID; 
    1921import com.orientechnologies.orient.core.metadata.schema.OType; 
    20 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2122import com.orientechnologies.orient.core.record.impl.ODocumentHelper; 
    2223import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
     
    3839        @Override 
    3940        @SuppressWarnings("unchecked") 
    40         protected boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    41                         final Object iRight) { 
     41        protected boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     42                        final Object iRight, OCommandContext iContext) { 
    4243                final Object right = OType.convert(iRight, iLeft.getClass()); 
    4344                if (right == null) 
     
    6667    else { 
    6768      if (iRight instanceof OSQLFilterItemParameter && 
    68               ((OSQLFilterItemParameter) iRight).getValue(null) instanceof ORID) 
    69         return (ORID) ((OSQLFilterItemParameter) iRight).getValue(null); 
     69              ((OSQLFilterItemParameter) iRight).getValue(null, null) instanceof ORID) 
     70        return (ORID) ((OSQLFilterItemParameter) iRight).getValue(null, null); 
    7071    } 
    7172 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorMinorEquals.java

    r19015 r19635  
    1616package com.orientechnologies.orient.core.sql.operator; 
    1717 
     18import com.orientechnologies.orient.core.command.OCommandContext; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1820import com.orientechnologies.orient.core.id.ORID; 
    1921import com.orientechnologies.orient.core.metadata.schema.OType; 
    20 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2122import com.orientechnologies.orient.core.record.impl.ODocumentHelper; 
    2223import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
     
    3839        @Override 
    3940        @SuppressWarnings("unchecked") 
    40         protected boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    41                         final Object iRight) { 
     41        protected boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     42                        final Object iRight, OCommandContext iContext) { 
    4243                final Object right = OType.convert(iRight, iLeft.getClass()); 
    4344                if (right == null) 
     
    6667      else { 
    6768        if (iRight instanceof OSQLFilterItemParameter && 
    68                 ((OSQLFilterItemParameter) iRight).getValue(null) instanceof ORID) 
    69           return (ORID) ((OSQLFilterItemParameter) iRight).getValue(null); 
     69                ((OSQLFilterItemParameter) iRight).getValue(null, null) instanceof ORID) 
     70          return (ORID) ((OSQLFilterItemParameter) iRight).getValue(null, null); 
    7071      } 
    7172 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorNot.java

    r19431 r19635  
    1616package com.orientechnologies.orient.core.sql.operator; 
    1717 
     18import com.orientechnologies.orient.core.command.OCommandContext; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1820import com.orientechnologies.orient.core.id.ORID; 
    19 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2021import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
    2122 
     
    3334 
    3435        @Override 
    35         public Object evaluateRecord(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    36                         final Object iRight) { 
     36        public Object evaluateRecord(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     37                        final Object iRight, OCommandContext iContext) { 
    3738                if (iLeft == null) 
    3839                        return false; 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorNotEquals.java

    r19015 r19635  
    1616package com.orientechnologies.orient.core.sql.operator; 
    1717 
     18import com.orientechnologies.orient.core.command.OCommandContext; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1820import com.orientechnologies.orient.core.id.ORID; 
    19 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2021import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
    2122 
     
    3334 
    3435        @Override 
    35         protected boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    36                         final Object iRight) { 
     36        protected boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     37                        final Object iRight, OCommandContext iContext) { 
    3738                return !OQueryOperatorEquals.equals(iLeft, iRight); 
    3839        } 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorOr.java

    r19431 r19635  
    1616package com.orientechnologies.orient.core.sql.operator; 
    1717 
     18import com.orientechnologies.orient.core.command.OCommandContext; 
     19import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    1820import com.orientechnologies.orient.core.id.ORID; 
    19 import com.orientechnologies.orient.core.record.ORecordInternal; 
    2021import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
    2122 
     
    3334 
    3435        @Override 
    35         public Object evaluateRecord(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    36                         final Object iRight) { 
     36        public Object evaluateRecord(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     37                        final Object iRight, OCommandContext iContext) { 
    3738                if (iLeft == null) 
    3839                        return false; 
  • trunk/Res_Orient/core/java/com/orientechnologies/orient/core/sql/operator/OQueryOperatorTraverse.java

    r19299 r19635  
    2323import java.util.Set; 
    2424 
     25import com.orientechnologies.orient.core.command.OCommandContext; 
     26import com.orientechnologies.orient.core.db.record.OIdentifiable; 
    2527import com.orientechnologies.orient.core.db.record.ORecordElement; 
    2628import com.orientechnologies.orient.core.exception.ORecordNotFoundException; 
    2729import com.orientechnologies.orient.core.id.ORID; 
    2830import com.orientechnologies.orient.core.query.OQueryRuntimeValueMulti; 
    29 import com.orientechnologies.orient.core.record.ORecordInternal; 
    3031import com.orientechnologies.orient.core.record.impl.ODocument; 
    3132import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; 
     
    6061 
    6162        @Override 
    62         protected boolean evaluateExpression(final ORecordInternal<?> iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
    63                         final Object iRight) { 
     63        protected boolean evaluateExpression(final OIdentifiable iRecord, final OSQLFilterCondition iCondition, final Object iLeft, 
     64                        final Object iRight, final OCommandContext iContext) { 
    6465                final OSQLFilterCondition condition; 
    6566                final Object target; 
     
    7475 
    7576                final Set<ORID> evaluatedRecords = new HashSet<ORID>(); 
    76                 return traverse(iRecord, iCondition, condition, target, 0, evaluatedRecords); 
     77                return traverse(target, condition, 0, evaluatedRecords, iContext); 
    7778        } 
    7879 
    7980        @SuppressWarnings("unchecked") 
    80         private boolean traverse(final ORecordInternal<?> iRecord, final OSQLFilterCondition iRootCondition, 
    81                         final OSQLFilterCondition iCondition, Object iTarget, final int iLevel, final Set<ORID> iEvaluatedRecords) { 
     81        private boolean traverse(Object iTarget, final OSQLFilterCondition iCondition, final int iLevel, 
     82                        final Set<ORID> iEvaluatedRecords, final OCommandContext iContext) { 
    8283                if (endDeepLevel > -1 && iLevel > endDeepLevel) 
    8384                        return false; 
     
    109110                                } 
    110111 
    111                         if (iLevel >= startDeepLevel && (Boolean) iCondition.evaluate(target) == Boolean.TRUE) 
     112                        if (iLevel >= startDeepLevel && (Boolean) iCondition.evaluate(target, iContext) == Boolean.TRUE) 
    112113                                return true; 
    113114 
     
    117118                                        // ANY 
    118119                                        for (final String fieldName : target.fieldNames()) 
    119                                                 if (traverse(iRecord, iRootCondition, iCondition, target.rawField(fieldName), iLevel + 1, iEvaluatedRecords)) 
     120                                                if (traverse(target.rawField(fieldName), iCondition, iLevel + 1, iEvaluatedRecords, iContext)) 
    120121                                                        return true; 
    121122                                } else if (cfgField.equalsIgnoreCase(OSQLFilterItemFieldAny.FULL_NAME)) { 
    122123                                        // ALL 
    123124                                        for (final String fieldName : target.fieldNames()) 
    124                                                 if (!traverse(iRecord, iRootCondition, iCondition, target.rawField(fieldName), iLevel + 1, iEvaluatedRecords)) 
     125                                                if (!traverse(target.rawField(fieldName), iCondition, iLevel + 1, iEvaluatedRecords, iContext)) 
    125126                                                        return false; 
    126127                                        return true; 
    127128                                } else { 
    128                                         if (traverse(iRecord, iRootCondition, iCondition, target.rawField(cfgField), iLevel + 1, iEvaluatedRecords)) 
     129                                        if (traverse(target.rawField(cfgField), iCondition, iLevel + 1, iEvaluatedRecords, iContext)) 
    129130                                                return true; 
    130131                                } 
     
    135136                        final OQueryRuntimeValueMulti multi = (OQueryRuntimeValueMulti) iTarget; 
    136137                        for (final Object o : multi.values) { 
    137                                 if (traverse(iRecord, iRootCondition, iCondition, o, iLevel + 1, iEvaluatedRecords) == Boolean.TRUE) 
     138                                if (traverse(o, iCondition, iLevel + 1, iEvaluatedRecords, iContext) == Boolean.TRUE) 
    138139                                        return true; 
    139140                        } 
     
    142143                        final Collection<Object> collection = (Collection<Object>) iTarget; 
    143144                        for (final Object o : collection) { 
    144                                 if (traverse(iRecord, iRootCondition, iCondition, o, iLevel + 1, iEvaluatedRecords) == Boolean.TRUE) 
     145                                if (traverse(o, iCondition, iLevel + 1, iEvaluatedRecords, iContext) == Boolean.TRUE) 
    145146                                        return true; 
    146147                        } 
     
    149150                        final Map<Object, Object> map = (Map<Object, Object>) iTarget; 
    150151                &nb