diff --git a/engine/src/main/java/com/arcadedb/database/DatabaseContext.java b/engine/src/main/java/com/arcadedb/database/DatabaseContext.java index 84e66e7cdf..c52398b198 100644 --- a/engine/src/main/java/com/arcadedb/database/DatabaseContext.java +++ b/engine/src/main/java/com/arcadedb/database/DatabaseContext.java @@ -28,6 +28,8 @@ * Thread local to store transaction data. */ public class DatabaseContext extends ThreadLocal> { + public static final DatabaseContext INSTANCE = new DatabaseContext(); + public DatabaseContextTL init(final DatabaseInternal database) { return init(database, null); } @@ -64,9 +66,8 @@ public DatabaseContextTL init(final DatabaseInternal database, final Transaction } } - if (current.transactions.isEmpty()) - current.transactions.add( - firstTransaction != null ? firstTransaction : new TransactionContext(database.getWrappedDatabaseInstance())); + if (current.transactions.isEmpty()) current.transactions.add( + firstTransaction != null ? firstTransaction : new TransactionContext(database.getWrappedDatabaseInstance())); return current; } @@ -98,8 +99,7 @@ public void clear() { public DatabaseContextTL getContext(final String name) { final DatabaseContextTL ctx = getContextIfExists(name); - if (ctx == null) - throw new DatabaseOperationException("Transaction context not found on current thread"); + if (ctx == null) throw new DatabaseOperationException("Transaction context not found on current thread"); return ctx; } @@ -110,8 +110,7 @@ public DatabaseContextTL getContextIfExists(final String name) { public DatabaseContextTL removeContext(final String name) { final Map map = get(); - if (map != null) - return map.remove(name); + if (map != null) return map.remove(name); return null; } @@ -124,8 +123,7 @@ public Database getActiveDatabase() { final DatabaseContextTL tl = map.values().iterator().next(); if (tl != null) { final TransactionContext tx = tl.getLastTransaction(); - if (tx != null) - return tx.getDatabase(); + if (tx != null) return tx.getDatabase(); } } return null; @@ -166,25 +164,21 @@ public Binary getTemporaryBuffer2() { } public TransactionContext getLastTransaction() { - if (transactions.isEmpty()) - return null; + if (transactions.isEmpty()) return null; return transactions.get(transactions.size() - 1); } public void pushTransaction(final TransactionContext tx) { - if (transactions.size() + 1 > maxNested) - throw new TransactionException("Exceeded number of " + transactions.size() - + " nested transactions. Check your code if you are beginning new transactions without closing the previous one by mistake. Otherwise change this limit with setMaxNested()"); + if (transactions.size() + 1 > maxNested) throw new TransactionException("Exceeded number of " + transactions.size() + + " nested transactions. Check your code if you are beginning new transactions without closing the previous one by mistake. Otherwise change this limit with setMaxNested()"); transactions.add(tx); } public TransactionContext popIfNotLastTransaction() { - if (transactions.isEmpty()) - return null; + if (transactions.isEmpty()) return null; - if (transactions.size() > 1) - return transactions.remove(transactions.size() - 1); + if (transactions.size() > 1) return transactions.remove(transactions.size() - 1); return transactions.get(0); } @@ -198,5 +192,4 @@ public void setMaxNested(final int maxNested) { } } - public static final DatabaseContext INSTANCE = new DatabaseContext(); } diff --git a/engine/src/main/java/com/arcadedb/database/LocalDatabase.java b/engine/src/main/java/com/arcadedb/database/LocalDatabase.java index bdb39d73c4..57af797026 100644 --- a/engine/src/main/java/com/arcadedb/database/LocalDatabase.java +++ b/engine/src/main/java/com/arcadedb/database/LocalDatabase.java @@ -151,18 +151,14 @@ protected LocalDatabase(final String path, final ComponentFile.MODE mode, final this.executionPlanCache = new ExecutionPlanCache(this, configuration.getValueAsInteger(GlobalConfiguration.SQL_STATEMENT_CACHE)); - if (path.endsWith(File.separator)) - databasePath = path.substring(0, path.length() - 1); - else - databasePath = path; + if (path.endsWith(File.separator)) databasePath = path.substring(0, path.length() - 1); + else databasePath = path; configurationFile = new File(databasePath + File.separator + "configuration.json"); final int lastSeparatorPos = path.lastIndexOf(File.separator); - if (lastSeparatorPos > -1) - name = path.substring(lastSeparatorPos + 1); - else - name = path; + if (lastSeparatorPos > -1) name = path.substring(lastSeparatorPos + 1); + else name = path; checkDatabaseName(); @@ -170,17 +166,15 @@ protected LocalDatabase(final String path, final ComponentFile.MODE mode, final queryEngineManager = new QueryEngineManager(); graphEngine = new GraphEngine(this); - } catch (final Exception e) { - if (e instanceof DatabaseOperationException) - throw (DatabaseOperationException) e; - + } catch (DatabaseOperationException e) { + throw e; + } catch (Exception e) { throw new DatabaseOperationException("Error on creating new database instance", e); } } protected void open() { - if (!new File(databasePath).exists()) - throw new DatabaseOperationException("Database '" + databasePath + "' does not exist"); + if (!new File(databasePath).exists()) throw new DatabaseOperationException("Database '" + databasePath + "' does not exist"); if (configurationFile.exists()) { try { @@ -219,11 +213,9 @@ protected void create() { public void drop() { checkDatabaseIsOpen(); - if (isTransactionActive()) - throw new DatabaseOperationException("Cannot drop the database in transaction"); + if (isTransactionActive()) throw new DatabaseOperationException("Cannot drop the database in transaction"); - if (mode == ComponentFile.MODE.READ_ONLY) - throw new DatabaseIsReadOnlyException("Cannot drop database"); + if (mode == ComponentFile.MODE.READ_ONLY) throw new DatabaseIsReadOnlyException("Cannot drop database"); internalClose(true); @@ -243,8 +235,7 @@ public void close() { */ @Override public void kill() { - if (async != null) - async.kill(); + if (async != null) async.kill(); if (getTransaction().isActive()) // ROLLBACK ANY PENDING OPERATION @@ -261,10 +252,8 @@ public void kill() { if (lockFileLock != null) { lockFileLock.release(); } - if (lockFileIOChannel != null) - lockFileIOChannel.close(); - if (lockFileIO != null) - lockFileIO.close(); + if (lockFileIOChannel != null) lockFileIOChannel.close(); + if (lockFileIO != null) lockFileIO.close(); } catch (final IOException e) { // IGNORE IT } @@ -293,8 +282,7 @@ public DatabaseAsyncExecutor async() { if (async == null) { asyncLock.lock(); try { - if (async == null) - async = new DatabaseAsyncExecutorImpl(wrappedDatabaseInstance, getConfiguration()); + if (async == null) async = new DatabaseAsyncExecutorImpl(wrappedDatabaseInstance, getConfiguration()); } finally { asyncLock.unlock(); } @@ -317,8 +305,7 @@ public String getDatabasePath() { @Override public String getCurrentUserName() { final DatabaseContext.DatabaseContextTL dbContext = DatabaseContext.INSTANCE.getContextIfExists(databasePath); - if (dbContext == null) - return null; + if (dbContext == null) return null; final SecurityDatabaseUser user = dbContext.getCurrentUser(); return user != null ? user.getName() : null; } @@ -326,8 +313,7 @@ public String getCurrentUserName() { @Override public int getNestedTransactions() { final DatabaseContext.DatabaseContextTL dbContext = DatabaseContext.INSTANCE.getContextIfExists(databasePath); - if (dbContext != null) - return dbContext.transactions.size(); + if (dbContext != null) return dbContext.transactions.size(); return 0; } @@ -423,8 +409,7 @@ public void rollback() { @Override public void rollbackAllNested() { - if (!isTransactionActive()) - return; + if (!isTransactionActive()) return; stats.txRollbacks.incrementAndGet(); @@ -434,10 +419,8 @@ public void rollbackAllNested() { TransactionContext tx; while ((tx = current.popIfNotLastTransaction()) != null) { try { - if (tx.isActive()) - tx.rollback(); - else - break; + if (tx.isActive()) tx.rollback(); + else break; } catch (final InvalidDatabaseInstanceException e) { current.popIfNotLastTransaction().rollback(); @@ -495,18 +478,14 @@ public void scanType(final String typeName, final boolean polymorphic, final Doc return continueScan.get(); }, errorRecordCallback); - if (!continueScan.get()) - break; + if (!continueScan.get()) break; } success = true; } finally { - if (implicitTransaction) - if (success) - wrappedDatabaseInstance.commit(); - else - wrappedDatabaseInstance.rollback(); + if (implicitTransaction) if (success) wrappedDatabaseInstance.commit(); + else wrappedDatabaseInstance.rollback(); } return null; }); @@ -569,71 +548,56 @@ public Iterator iterateBucket(final String bucketName) { } public void checkPermissionsOnDatabase(final SecurityDatabaseUser.DATABASE_ACCESS access) { - if (security == null) - return; + if (security == null) return; final DatabaseContext.DatabaseContextTL dbContext = DatabaseContext.INSTANCE.getContextIfExists(databasePath); - if (dbContext == null) - return; + if (dbContext == null) return; final SecurityDatabaseUser user = dbContext.getCurrentUser(); - if (user == null) - return; + if (user == null) return; - if (user.requestAccessOnDatabase(access)) - return; + if (user.requestAccessOnDatabase(access)) return; throw new SecurityException("User '" + user.getName() + "' is not allowed to " + access.fullName); } @Override public void checkPermissionsOnFile(final int fileId, final SecurityDatabaseUser.ACCESS access) { - if (security == null) - return; + if (security == null) return; final DatabaseContext.DatabaseContextTL dbContext = DatabaseContext.INSTANCE.getContextIfExists(databasePath); - if (dbContext == null) - return; + if (dbContext == null) return; final SecurityDatabaseUser user = dbContext.getCurrentUser(); - if (user == null) - return; + if (user == null) return; - if (user.requestAccessOnFile(fileId, access)) - return; + if (user.requestAccessOnFile(fileId, access)) return; String resource = "file '" + schema.getFileById(fileId).getName() + "'"; final DocumentType type = schema.getTypeByBucketId(fileId); - if (type != null) - resource = "type '" + type + "'"; + if (type != null) resource = "type '" + type + "'"; throw new SecurityException("User '" + user.getName() + "' is not allowed to " + access.fullName + " on " + resource); } @Override public long getResultSetLimit() { - if (security == null) - return -1L; + if (security == null) return -1L; final DatabaseContext.DatabaseContextTL dbContext = DatabaseContext.INSTANCE.getContextIfExists(databasePath); - if (dbContext == null) - return -1L; + if (dbContext == null) return -1L; final SecurityDatabaseUser user = dbContext.getCurrentUser(); - if (user == null) - return -1L; + if (user == null) return -1L; return user.getResultSetLimit(); } @Override public long getReadTimeout() { - if (security == null) - return -1L; + if (security == null) return -1L; final DatabaseContext.DatabaseContextTL dbContext = DatabaseContext.INSTANCE.getContextIfExists(databasePath); - if (dbContext == null) - return -1L; + if (dbContext == null) return -1L; final SecurityDatabaseUser user = dbContext.getCurrentUser(); - if (user == null) - return -1L; + if (user == null) return -1L; return user.getReadTimeout(); } @@ -642,8 +606,7 @@ public long getReadTimeout() { public boolean existsRecord(final RID rid) { stats.existsRecord.incrementAndGet(); - if (rid == null) - throw new IllegalArgumentException("Record is null"); + if (rid == null) throw new IllegalArgumentException("Record is null"); return (boolean) executeInReadLock((Callable) () -> { checkDatabaseIsOpen(); @@ -651,8 +614,7 @@ public boolean existsRecord(final RID rid) { // CHECK IN TX CACHE FIRST final TransactionContext tx = getTransaction(); Record record = tx.getRecordFromCache(rid); - if (record != null) - return true; + if (record != null) return true; return schema.getBucketById(rid.getBucketId()).existsRecord(rid); }); @@ -662,8 +624,7 @@ public boolean existsRecord(final RID rid) { public Record lookupByRID(final RID rid, final boolean loadContent) { stats.readRecord.incrementAndGet(); - if (rid == null) - throw new IllegalArgumentException("Record id is null"); + if (rid == null) throw new IllegalArgumentException("Record id is null"); return (Record) executeInReadLock((Callable) () -> { checkDatabaseIsOpen(); @@ -671,8 +632,7 @@ public Record lookupByRID(final RID rid, final boolean loadContent) { // CHECK IN TX CACHE FIRST final TransactionContext tx = getTransaction(); Record record = tx.getRecordFromCache(rid); - if (record != null) - return record; + if (record != null) return record; final DocumentType type = schema.getTypeByBucketId(rid.getBucketId()); @@ -680,8 +640,7 @@ public Record lookupByRID(final RID rid, final boolean loadContent) { if (!loadContent && tx.getIsolationLevel() == TRANSACTION_ISOLATION_LEVEL.REPEATABLE_READ) // FORCE LOAD OF CONTENT TO GUARANTEE THE LOADING OF MULTI-PAGE RECORD INTO THE TX CONTEXT loadRecordContent = true; - else - loadRecordContent = loadContent; + else loadRecordContent = loadContent; if (loadRecordContent || type == null) { final Binary buffer = schema.getBucketById(rid.getBucketId()).getRecord(rid); @@ -710,9 +669,8 @@ public IndexCursor lookupByKey(final String type, final String[] keyNames, final final DocumentType t = schema.getType(type); final TypeIndex idx = t.getPolymorphicIndexByProperties(keyNames); - if (idx == null) - throw new IllegalArgumentException( - "No index has been created on type '" + type + "' properties " + Arrays.toString(keyNames)); + if (idx == null) throw new IllegalArgumentException( + "No index has been created on type '" + type + "' properties " + Arrays.toString(keyNames)); return idx.get(keyValues); }); @@ -729,8 +687,7 @@ public void unregisterCallback(final CALLBACK_EVENT event, final Callable final List> callbacks = this.callbacks.get(event); if (callbacks != null) { callbacks.remove(callback); - if (callbacks.isEmpty()) - this.callbacks.remove(event); + if (callbacks.isEmpty()) this.callbacks.remove(event); } } @@ -815,20 +772,16 @@ public void createRecordNoLock(final Record record, final String bucketName, fin if (record.getIdentity() != null) throw new IllegalArgumentException("Cannot create record " + record.getIdentity() + " because it is already persistent"); - if (mode == ComponentFile.MODE.READ_ONLY) - throw new DatabaseIsReadOnlyException("Cannot create a new record"); + if (mode == ComponentFile.MODE.READ_ONLY) throw new DatabaseIsReadOnlyException("Cannot create a new record"); setDefaultValues(record); - if (record instanceof MutableDocument) - ((MutableDocument) record).validate(); + if (record instanceof MutableDocument) ((MutableDocument) record).validate(); // INVOKE EVENT CALLBACKS - if (!events.onBeforeCreate(record)) - return; + if (!events.onBeforeCreate(record)) return; if (record instanceof Document) - if (!((RecordEventsRegistry) ((Document) record).getType().getEvents()).onBeforeCreate(record)) - return; + if (!((RecordEventsRegistry) ((Document) record).getType().getEvents()).onBeforeCreate(record)) return; boolean success = false; final boolean implicitTransaction = checkTransactionIsActive(autoTransaction); @@ -838,8 +791,7 @@ public void createRecordNoLock(final Record record, final String bucketName, fin if (bucketName == null && record instanceof Document) { final Document doc = (Document) record; bucket = (LocalBucket) doc.getType().getBucketIdByRecord(doc, DatabaseContext.INSTANCE.getContext(databasePath).asyncMode); - } else - bucket = (LocalBucket) schema.getBucketByName(bucketName); + } else bucket = (LocalBucket) schema.getBucketByName(bucketName); ((RecordInternal) record).setIdentity(bucket.createRecord(record, discardRecordAfter)); @@ -858,36 +810,28 @@ public void createRecordNoLock(final Record record, final String bucketName, fin // INVOKE EVENT CALLBACKS events.onAfterCreate(record); - if (record instanceof Document) - ((RecordEventsRegistry) ((Document) record).getType().getEvents()).onAfterCreate(record); + if (record instanceof Document) ((RecordEventsRegistry) ((Document) record).getType().getEvents()).onAfterCreate(record); } finally { if (implicitTransaction) { - if (success) - wrappedDatabaseInstance.commit(); - else - wrappedDatabaseInstance.rollback(); + if (success) wrappedDatabaseInstance.commit(); + else wrappedDatabaseInstance.rollback(); } } } @Override public void updateRecord(final Record record) { - if (record.getIdentity() == null) - throw new IllegalArgumentException("Cannot update the record because it is not persistent"); + if (record.getIdentity() == null) throw new IllegalArgumentException("Cannot update the record because it is not persistent"); - if (mode == ComponentFile.MODE.READ_ONLY) - throw new DatabaseIsReadOnlyException("Cannot update a record"); + if (mode == ComponentFile.MODE.READ_ONLY) throw new DatabaseIsReadOnlyException("Cannot update a record"); - if (record instanceof MutableDocument) - ((MutableDocument) record).validate(); + if (record instanceof MutableDocument) ((MutableDocument) record).validate(); // INVOKE EVENT CALLBACKS - if (!events.onBeforeUpdate(record)) - return; + if (!events.onBeforeUpdate(record)) return; if (record instanceof Document) - if (!((RecordEventsRegistry) ((Document) record).getType().getEvents()).onBeforeUpdate(record)) - return; + if (!((RecordEventsRegistry) ((Document) record).getType().getEvents()).onBeforeUpdate(record)) return; executeInReadLock(() -> { if (isTransactionActive()) { @@ -909,13 +853,11 @@ public void updateRecord(final Record record) { } catch (final IOException e) { throw new DatabaseOperationException("Error on update the record " + record.getIdentity() + " in transaction", e); } - } else - updateRecordNoLock(record, false); + } else updateRecordNoLock(record, false); // INVOKE EVENT CALLBACKS events.onAfterUpdate(record); - if (record instanceof Document) - ((RecordEventsRegistry) ((Document) record).getType().getEvents()).onAfterUpdate(record); + if (record instanceof Document) ((RecordEventsRegistry) ((Document) record).getType().getEvents()).onAfterUpdate(record); return null; }); @@ -923,9 +865,8 @@ public void updateRecord(final Record record) { public Document getOriginalDocument(final Record record) { final Binary originalBuffer = ((RecordInternal) record).getBuffer(); - if (originalBuffer == null) - throw new IllegalStateException("Cannot read original buffer for record " + record.getIdentity() - + ". In case of tx retry check the record is created inside the transaction"); + if (originalBuffer == null) throw new IllegalStateException("Cannot read original buffer for record " + record.getIdentity() + + ". In case of tx retry check the record is created inside the transaction"); originalBuffer.rewind(); return (Document) recordFactory.newImmutableRecord(this, ((Document) record).getType(), record.getIdentity(), originalBuffer, null); @@ -959,10 +900,8 @@ public void updateRecordNoLock(final Record record, final boolean discardRecordA } finally { if (implicitTransaction) { - if (success) - wrappedDatabaseInstance.commit(); - else - wrappedDatabaseInstance.rollback(); + if (success) wrappedDatabaseInstance.commit(); + else wrappedDatabaseInstance.rollback(); } } } @@ -977,18 +916,14 @@ public void deleteRecord(final Record record) { @Override public void deleteRecordNoLock(final Record record) { - if (record.getIdentity() == null) - throw new IllegalArgumentException("Cannot delete a non persistent record"); + if (record.getIdentity() == null) throw new IllegalArgumentException("Cannot delete a non persistent record"); - if (mode == ComponentFile.MODE.READ_ONLY) - throw new DatabaseIsReadOnlyException("Cannot delete record " + record.getIdentity()); + if (mode == ComponentFile.MODE.READ_ONLY) throw new DatabaseIsReadOnlyException("Cannot delete record " + record.getIdentity()); // INVOKE EVENT CALLBACKS - if (!events.onBeforeDelete(record)) - return; + if (!events.onBeforeDelete(record)) return; if (record instanceof Document) - if (!((RecordEventsRegistry) ((Document) record).getType().getEvents()).onBeforeDelete(record)) - return; + if (!((RecordEventsRegistry) ((Document) record).getType().getEvents()).onBeforeDelete(record)) return; boolean success = false; final boolean implicitTransaction = checkTransactionIsActive(autoTransaction); @@ -996,32 +931,27 @@ public void deleteRecordNoLock(final Record record) { try { final LocalBucket bucket = schema.getBucketById(record.getIdentity().getBucketId()); - if (record instanceof Document) - indexer.deleteDocument((Document) record); + if (record instanceof Document) indexer.deleteDocument((Document) record); if (record instanceof Edge) { graphEngine.deleteEdge((Edge) record); } else if (record instanceof Vertex) { graphEngine.deleteVertex((VertexInternal) record); - } else - bucket.deleteRecord(record.getIdentity()); + } else bucket.deleteRecord(record.getIdentity()); success = true; // INVOKE EVENT CALLBACKS events.onAfterDelete(record); - if (record instanceof Document) - ((RecordEventsRegistry) ((Document) record).getType().getEvents()).onAfterDelete(record); + if (record instanceof Document) ((RecordEventsRegistry) ((Document) record).getType().getEvents()).onAfterDelete(record); final TransactionContext transaction = getTransaction(); transaction.updateBucketRecordDelta(bucket.getFileId(), -1); } finally { if (implicitTransaction) { - if (success) - wrappedDatabaseInstance.commit(); - else - wrappedDatabaseInstance.rollback(); + if (success) wrappedDatabaseInstance.commit(); + else wrappedDatabaseInstance.rollback(); } } } @@ -1050,13 +980,11 @@ public boolean transaction(final TransactionScope txBlock, final boolean joinCur @Override public boolean transaction(final TransactionScope txBlock, final boolean joinCurrentTx, int attempts, final OkCallback ok, final ErrorCallback error) { - if (txBlock == null) - throw new IllegalArgumentException("Transaction block is null"); + if (txBlock == null) throw new IllegalArgumentException("Transaction block is null"); ArcadeDBException lastException = null; - if (attempts < 1) - attempts = 1; + if (attempts < 1) attempts = 1; final int retryDelay = GlobalConfiguration.TX_RETRY_DELAY.getValueAsInteger(); @@ -1064,18 +992,14 @@ public boolean transaction(final TransactionScope txBlock, final boolean joinCur boolean createdNewTx = true; try { - if (joinCurrentTx && wrappedDatabaseInstance.isTransactionActive()) - createdNewTx = false; - else - wrappedDatabaseInstance.begin(); + if (joinCurrentTx && wrappedDatabaseInstance.isTransactionActive()) createdNewTx = false; + else wrappedDatabaseInstance.begin(); txBlock.execute(); - if (createdNewTx) - wrappedDatabaseInstance.commit(); + if (createdNewTx) wrappedDatabaseInstance.commit(); - if (ok != null) - ok.call(); + if (ok != null) ok.call(); // OK return createdNewTx; @@ -1083,28 +1007,23 @@ public boolean transaction(final TransactionScope txBlock, final boolean joinCur } catch (final NeedRetryException | DuplicatedKeyException e) { // RETRY lastException = e; - if (wrappedDatabaseInstance.isTransactionActive()) - wrappedDatabaseInstance.rollback(); + if (wrappedDatabaseInstance.isTransactionActive()) wrappedDatabaseInstance.rollback(); - if (error != null) - error.call(e); + if (error != null) error.call(e); delayBetweenRetries(retryDelay); } catch (final Throwable e) { final TransactionContext tx = getTransaction(); - if (tx != null && tx.isActive()) - rollback(); + if (tx != null && tx.isActive()) rollback(); - if (error != null) - error.call(e); + if (error != null) error.call(e); throw e; } } - if (error != null) - error.call(lastException); + if (error != null) error.call(lastException); throw lastException; } @@ -1133,8 +1052,7 @@ public PageManager getPageManager() { @Override public MutableDocument newDocument(final String typeName) { - if (typeName == null) - throw new IllegalArgumentException("Type is null"); + if (typeName == null) throw new IllegalArgumentException("Type is null"); final LocalDocumentType type = schema.getType(typeName); if (!type.getClass().equals(LocalDocumentType.class)) @@ -1147,22 +1065,19 @@ public MutableDocument newDocument(final String typeName) { @Override public MutableEmbeddedDocument newEmbeddedDocument(final EmbeddedModifier modifier, final String typeName) { - if (typeName == null) - throw new IllegalArgumentException("Type is null"); + if (typeName == null) throw new IllegalArgumentException("Type is null"); final LocalDocumentType type = schema.getType(typeName); - if (!type.getClass().equals(LocalDocumentType.class)) - throw new IllegalArgumentException( - "Cannot create an embedded document of type '" + typeName + "' because it is a " + type.getClass().getName() - + " instead of a document type "); + if (!type.getClass().equals(LocalDocumentType.class)) throw new IllegalArgumentException( + "Cannot create an embedded document of type '" + typeName + "' because it is a " + type.getClass().getName() + + " instead of a document type "); return new MutableEmbeddedDocument(wrappedDatabaseInstance, type, modifier); } @Override public MutableVertex newVertex(final String typeName) { - if (typeName == null) - throw new IllegalArgumentException("Type is null"); + if (typeName == null) throw new IllegalArgumentException("Type is null"); final LocalDocumentType type = schema.getType(typeName); if (!type.getClass().equals(LocalVertexType.class)) @@ -1177,14 +1092,12 @@ public Edge newEdgeByKeys(final String sourceVertexType, final String[] sourceVe final Object[] sourceVertexKeyValues, final String destinationVertexType, final String[] destinationVertexKeyNames, final Object[] destinationVertexKeyValues, final boolean createVertexIfNotExist, final String edgeType, final boolean bidirectional, final Object... properties) { - if (sourceVertexKeyNames == null) - throw new IllegalArgumentException("Source vertex key is null"); + if (sourceVertexKeyNames == null) throw new IllegalArgumentException("Source vertex key is null"); if (sourceVertexKeyNames.length != sourceVertexKeyValues.length) throw new IllegalArgumentException("Source vertex key and value arrays have different sizes"); - if (destinationVertexKeyNames == null) - throw new IllegalArgumentException("Destination vertex key is null"); + if (destinationVertexKeyNames == null) throw new IllegalArgumentException("Destination vertex key is null"); if (destinationVertexKeyNames.length != destinationVertexKeyValues.length) throw new IllegalArgumentException("Destination vertex key and value arrays have different sizes"); @@ -1198,12 +1111,10 @@ public Edge newEdgeByKeys(final String sourceVertexType, final String[] sourceVe for (int i = 0; i < sourceVertexKeyNames.length; ++i) ((MutableVertex) sourceVertex).set(sourceVertexKeyNames[i], sourceVertexKeyValues[i]); ((MutableVertex) sourceVertex).save(); - } else - throw new IllegalArgumentException( - "Cannot find source vertex with key " + Arrays.toString(sourceVertexKeyNames) + "=" + Arrays.toString( - sourceVertexKeyValues)); - } else - sourceVertex = v1Result.next().getIdentity().asVertex(); + } else throw new IllegalArgumentException( + "Cannot find source vertex with key " + Arrays.toString(sourceVertexKeyNames) + "=" + Arrays.toString( + sourceVertexKeyValues)); + } else sourceVertex = v1Result.next().getIdentity().asVertex(); final Iterator v2Result = lookupByKey(destinationVertexType, destinationVertexKeyNames, destinationVertexKeyValues); @@ -1214,12 +1125,10 @@ public Edge newEdgeByKeys(final String sourceVertexType, final String[] sourceVe for (int i = 0; i < destinationVertexKeyNames.length; ++i) ((MutableVertex) destinationVertex).set(destinationVertexKeyNames[i], destinationVertexKeyValues[i]); ((MutableVertex) destinationVertex).save(); - } else - throw new IllegalArgumentException( - "Cannot find destination vertex with key " + Arrays.toString(destinationVertexKeyNames) + "=" + Arrays.toString( - destinationVertexKeyValues)); - } else - destinationVertex = v2Result.next().getIdentity().asVertex(); + } else throw new IllegalArgumentException( + "Cannot find destination vertex with key " + Arrays.toString(destinationVertexKeyNames) + "=" + Arrays.toString( + destinationVertexKeyValues)); + } else destinationVertex = v2Result.next().getIdentity().asVertex(); stats.createRecord.incrementAndGet(); @@ -1229,11 +1138,9 @@ public Edge newEdgeByKeys(final String sourceVertexType, final String[] sourceVe public Edge newEdgeByKeys(final Vertex sourceVertex, final String destinationVertexType, final String[] destinationVertexKeyNames, final Object[] destinationVertexKeyValues, final boolean createVertexIfNotExist, final String edgeType, final boolean bidirectional, final Object... properties) { - if (sourceVertex == null) - throw new IllegalArgumentException("Source vertex is null"); + if (sourceVertex == null) throw new IllegalArgumentException("Source vertex is null"); - if (destinationVertexKeyNames == null) - throw new IllegalArgumentException("Destination vertex key is null"); + if (destinationVertexKeyNames == null) throw new IllegalArgumentException("Destination vertex key is null"); if (destinationVertexKeyNames.length != destinationVertexKeyValues.length) throw new IllegalArgumentException("Destination vertex key and value arrays have different sizes"); @@ -1247,12 +1154,10 @@ public Edge newEdgeByKeys(final Vertex sourceVertex, final String destinationVer for (int i = 0; i < destinationVertexKeyNames.length; ++i) ((MutableVertex) destinationVertex).set(destinationVertexKeyNames[i], destinationVertexKeyValues[i]); ((MutableVertex) destinationVertex).save(); - } else - throw new IllegalArgumentException( - "Cannot find destination vertex with key " + Arrays.toString(destinationVertexKeyNames) + "=" + Arrays.toString( - destinationVertexKeyValues)); - } else - destinationVertex = v2Result.next().getIdentity().asVertex(); + } else throw new IllegalArgumentException( + "Cannot find destination vertex with key " + Arrays.toString(destinationVertexKeyNames) + "=" + Arrays.toString( + destinationVertexKeyValues)); + } else destinationVertex = v2Result.next().getIdentity().asVertex(); stats.createRecord.incrementAndGet(); @@ -1312,8 +1217,7 @@ public QueryEngine getQueryEngine(final String language) { engine = queryEngineManager.getInstance(language, this); if (engine.isReusable()) { final QueryEngine prev = reusableQueryEngines.putIfAbsent(language, engine); - if (prev != null) - engine = prev; + if (prev != null) engine = prev; } } @@ -1387,10 +1291,8 @@ public Select select() { * Returns true if two databases are the same. */ public boolean equals(final Object o) { - if (this == o) - return true; - if (!(o instanceof Database)) - return false; + if (this == o) return true; + if (!(o instanceof Database)) return false; final Database other = (Database) o; return Objects.equals(getDatabasePath(), other.getDatabasePath()); @@ -1471,8 +1373,7 @@ public RET executeLockingFiles(final Collection fileIds, Callable throw new DatabaseOperationException("Error during write lock", e); } finally { - if (lockedFiles != null) - transactionManager.unlockFilesInOrder(lockedFiles); + if (lockedFiles != null) transactionManager.unlockFilesInOrder(lockedFiles); } } @@ -1572,12 +1473,10 @@ public Database setEdgeListSize(final int size) { @Override public int getNewEdgeListSize(final int previousSize) { - if (previousSize == 0) - return edgeListSize; + if (previousSize == 0) return edgeListSize; int newSize = previousSize * 2; - if (newSize > MAX_RECOMMENDED_EDGE_LIST_CHUNK_SIZE) - newSize = MAX_RECOMMENDED_EDGE_LIST_CHUNK_SIZE; + if (newSize > MAX_RECOMMENDED_EDGE_LIST_CHUNK_SIZE) newSize = MAX_RECOMMENDED_EDGE_LIST_CHUNK_SIZE; return newSize; } @@ -1586,10 +1485,8 @@ public Map getWrappers() { } public void setWrapper(final String name, final Object instance) { - if (instance == null) - this.wrappers.remove(name); - else - this.wrappers.put(name, instance); + if (instance == null) this.wrappers.remove(name); + else this.wrappers.put(name, instance); } public QueryEngineManager getQueryEngineManager() { @@ -1604,8 +1501,7 @@ public void saveConfiguration() throws IOException { public Record invokeAfterReadEvents(Record record) { // INVOKE EVENT CALLBACKS record = events.onAfterRead(record); - if (record == null) - return null; + if (record == null) return null; if (record instanceof Document) { final DocumentType type = ((Document) record).getType(); if (type != null) { @@ -1636,10 +1532,8 @@ private void lockDatabase() { } catch (final Exception e) { try { - if (lockFileIOChannel != null) - lockFileIOChannel.close(); - if (lockFileIO != null) - lockFileIO.close(); + if (lockFileIOChannel != null) lockFileIOChannel.close(); + if (lockFileIO != null) lockFileIO.close(); } catch (final Exception e2) { // IGNORE } @@ -1667,14 +1561,12 @@ private void internalClose(final boolean drop) { } executeInWriteLock(() -> { - if (!open) - return null; + if (!open) return null; open = false; try { - if (async != null) - async.close(); + if (async != null) async.close(); } catch (final Throwable e) { LogManager.instance() .log(this, Level.WARNING, "Error on stopping asynchronous manager during closing operation for database '%s'", e, name); @@ -1721,12 +1613,9 @@ private void internalClose(final boolean drop) { lockFileLock.release(); //LogManager.instance().log(this, Level.INFO, "RELEASED DATABASE FILE '%s' (thread=%s)", null, lockFile, Thread.currentThread().getId()); } - if (lockFileIOChannel != null) - lockFileIOChannel.close(); - if (lockFileIO != null) - lockFileIO.close(); - if (lockFile.exists()) - Files.delete(Paths.get(lockFile.getAbsolutePath())); + if (lockFileIOChannel != null) lockFileIOChannel.close(); + if (lockFileIO != null) lockFileIO.close(); + if (lockFile.exists()) Files.delete(Paths.get(lockFile.getAbsolutePath())); if (lockFile.exists() && !lockFile.delete()) LogManager.instance().log(this, Level.WARNING, "Error on deleting lock file '%s'", lockFile); @@ -1766,8 +1655,7 @@ private void checkForRecovery() throws IOException { if (mode == ComponentFile.MODE.READ_WRITE) { lockFile.createNewFile(); lockDatabase(); - } else - lockFile = null; + } else lockFile = null; } } @@ -1784,19 +1672,15 @@ private void openInternal() { try { schema = new LocalSchema(wrappedDatabaseInstance, databasePath, security); - if (fileManager.getFiles().isEmpty()) - schema.create(mode); - else - schema.load(mode, true); + if (fileManager.getFiles().isEmpty()) schema.create(mode); + else schema.load(mode, true); serializer.setDateImplementation(configuration.getValue(GlobalConfiguration.DATE_IMPLEMENTATION)); serializer.setDateTimeImplementation(configuration.getValue(GlobalConfiguration.DATE_TIME_IMPLEMENTATION)); - if (mode == ComponentFile.MODE.READ_WRITE) - checkForRecovery(); + if (mode == ComponentFile.MODE.READ_WRITE) checkForRecovery(); - if (security != null) - security.updateSchema(this); + if (security != null) security.updateSchema(this); Profiler.INSTANCE.registerDatabase(this); @@ -1812,18 +1696,15 @@ private void openInternal() { } catch (final Exception e) { open = false; - if (e instanceof DatabaseOperationException) - throw (DatabaseOperationException) e; + if (e instanceof DatabaseOperationException) throw (DatabaseOperationException) e; throw new DatabaseOperationException("Error on creating new database instance", e); } } protected void checkDatabaseIsOpen() { - if (!open) - throw new DatabaseIsClosedException(name); - if (DatabaseContext.INSTANCE.getContextIfExists(databasePath) == null) - DatabaseContext.INSTANCE.init(this); + if (!open) throw new DatabaseIsClosedException(name); + if (DatabaseContext.INSTANCE.getContextIfExists(databasePath) == null) DatabaseContext.INSTANCE.init(this); } private void setDefaultValues(final Record record) { diff --git a/engine/src/main/java/com/arcadedb/query/sql/executor/MultiValue.java b/engine/src/main/java/com/arcadedb/query/sql/executor/MultiValue.java index ab6b0cd851..8970420c6d 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/executor/MultiValue.java +++ b/engine/src/main/java/com/arcadedb/query/sql/executor/MultiValue.java @@ -30,6 +30,7 @@ import java.lang.reflect.*; import java.util.*; import java.util.logging.*; +import java.util.stream.StreamSupport; /** * Handles Multi-value types such as Arrays, Collections and Maps. It recognizes special Arcade collections. @@ -48,8 +49,7 @@ public class MultiValue { */ public static boolean isMultiValue(final Class iType) { return Collection.class.isAssignableFrom(iType) || Map.class.isAssignableFrom(iType) || MultiIterator.class.isAssignableFrom( - iType) || ( - Iterable.class.isAssignableFrom(iType) && !Identifiable.class.isAssignableFrom(iType)) || iType.isArray() + iType) || (Iterable.class.isAssignableFrom(iType) && !Identifiable.class.isAssignableFrom(iType)) || iType.isArray() || ResultSet.class.isAssignableFrom(iType); } @@ -76,29 +76,16 @@ public static boolean isIterable(final Object iObject) { * @return the size of the multi value object */ public static int getSize(final Object object) { - if (object == null) - return 0; - - if (!isMultiValue(object)) - return 0; - - if (object instanceof Collection) - return ((Collection) object).size(); - else if (object instanceof Map) - return ((Map) object).size(); - else if (object.getClass().isArray()) - return Array.getLength(object); - else if ((object instanceof ResettableIterator)) - return (int) ((ResettableIterator) object).countEntries(); - else if ((object instanceof Iterable)) { - int i = 0; - for (final Object o : (Iterable) object) { - i++; - } - return i; - } else if ((object instanceof Iterator)) { - return (int) CollectionUtils.countEntries((Iterator) object); - } + if (object == null) return 0; + + if (!isMultiValue(object)) return 0; + + if (object instanceof Collection collection) return collection.size(); + else if (object instanceof Map map) return map.size(); + else if (object.getClass().isArray()) return Array.getLength(object); + else if (object instanceof ResettableIterator resettableIterator) return (int) resettableIterator.countEntries(); + else if (object instanceof Iterable iterable) return (int) StreamSupport.stream(iterable.spliterator(), false).count(); + else if (object instanceof Iterator iterator) return (int) CollectionUtils.countEntries(iterator); return 0; } @@ -111,15 +98,11 @@ else if ((object instanceof Iterable)) { * @return the size of the multi value object, -1 if the size is not available without computing */ public static int getSizeIfAvailable(final Object object) { - if (object == null) - return 0; - - if (object instanceof Collection) - return ((Collection) object).size(); - else if (object instanceof Map) - return ((Map) object).size(); - else if (object.getClass().isArray()) - return Array.getLength(object); + if (object == null) return 0; + + if (object instanceof Collection collection) return collection.size(); + else if (object instanceof Map map) return map.size(); + else if (object.getClass().isArray()) return Array.getLength(object); return -1; } @@ -131,24 +114,17 @@ else if (object.getClass().isArray()) * @return The first item if any */ public static Object getFirstValue(final Object object) { - if (object == null) - return null; + if (object == null) return null; - if (!isMultiValue(object)) - return null; + if (!isMultiValue(object)) return null; - if (getSizeIfAvailable(object) == 0) - return null; + if (getSizeIfAvailable(object) == 0) return null; try { - if (object instanceof List) - return ((List) object).get(0); - else if (object instanceof Iterable) - return ((Iterable) object).iterator().next(); - else if (object instanceof Map) - return ((Map) object).values().iterator().next(); - else if (object.getClass().isArray()) - return Array.get(object, 0); + if (object instanceof List list) return list.get(0); + else if (object instanceof Iterable iterable) return iterable.iterator().next(); + else if (object instanceof Map map) return map.values().iterator().next(); + else if (object.getClass().isArray()) return Array.get(object, 0); } catch (final RuntimeException e) { // IGNORE IT LogManager.instance() @@ -166,30 +142,25 @@ else if (object.getClass().isArray()) * @return The last item if any */ public static Object getLastValue(final Object object) { - if (object == null) - return null; + if (object == null) return null; - if (!isMultiValue(object)) - return null; + if (!isMultiValue(object)) return null; - if (getSizeIfAvailable(object) == 0) - return null; + if (getSizeIfAvailable(object) == 0) return null; try { - if (object instanceof List) - return ((List) object).get(((List) object).size() - 1); - else if (object instanceof Iterable) { + if (object instanceof List list) return list.get(list.size() - 1); + else if (object instanceof Iterable iterable) { Object last = null; - for (final Object o : (Iterable) object) + for (final Object o : iterable) last = o; return last; - } else if (object instanceof Map) { + } else if (object instanceof Map map) { Object last = null; - for (final Object o : ((Map) object).values()) + for (final Object o : map.values()) last = o; return last; - } else if (object.getClass().isArray()) - return Array.get(object, Array.getLength(object) - 1); + } else if (object.getClass().isArray()) return Array.get(object, Array.getLength(object) - 1); } catch (final RuntimeException e) { // IGNORE IT LogManager.instance() @@ -208,37 +179,32 @@ else if (object instanceof Iterable) { * @return The first item if any */ public static Object getValue(final Object iObject, final int iIndex) { - if (iObject == null) - return null; + if (iObject == null) return null; - if (!isMultiValue(iObject)) - return null; + if (!isMultiValue(iObject)) return null; final int size = MultiValue.getSizeIfAvailable(iObject); - if (size > -1 && !(iObject instanceof Iterator) && iIndex > size) - return null; + if (size > -1 && !(iObject instanceof Iterator) && iIndex > size) return null; try { - if (iObject instanceof List) - return ((List) iObject).get(iIndex); - else if (iObject instanceof Set) { + if (iObject instanceof List list) return (list.get(iIndex)); + else if (iObject instanceof Set set) { int i = 0; - for (final Object o : ((Set) iObject)) { + for (final Object o : set) { if (i++ == iIndex) { return o; } } - } else if (iObject instanceof Map) { + } else if (iObject instanceof Map map) { int i = 0; - for (final Object o : ((Map) iObject).values()) { + for (final Object o : map.values()) { if (i++ == iIndex) { return o; } } } else if (iObject.getClass().isArray()) { - if (iIndex >= Array.getLength(iObject)) - return null; + if (iIndex >= Array.getLength(iObject)) return null; return Array.get(iObject, iIndex); } else if (iObject instanceof Iterator || iObject instanceof Iterable) { @@ -249,14 +215,12 @@ else if (iObject instanceof Set) { for (int i = 0; it.hasNext(); ++i) { final Object o = it.next(); if (i == iIndex) { - if (it instanceof ResettableIterator) - ((ResettableIterator) it).reset(); + if (it instanceof ResettableIterator resettableIterator) resettableIterator.reset(); return o; } } - if (it instanceof ResettableIterator) - ((ResettableIterator) it).reset(); + if (it instanceof ResettableIterator resettableIterator) resettableIterator.reset(); } } } catch (final RuntimeException e) { @@ -268,17 +232,17 @@ else if (iObject instanceof Set) { } /** - * Sets the value of the Multi-value object (array or collection) at iIndex + * Sets the value of the Multi-value object (array or collection) at index * - * @param iObject Multi-value object (array, collection) - * @param iValue The value to set at this specified index. - * @param iIndex integer as the position requested + * @param multiValue Multi-value object (array, collection) + * @param value The value to set at this specified index. + * @param index integer as the position requested */ - public static void setValue(final Object iObject, final Object iValue, final int iIndex) { - if (iObject instanceof List) { - ((List) iObject).set(iIndex, iValue); - } else if (iObject.getClass().isArray()) { - Array.set(iObject, iIndex, iValue); + public static void setValue(final Object multiValue, final Object value, final int index) { + if (multiValue instanceof List list) { + list.set(index, value); + } else if (multiValue.getClass().isArray()) { + Array.set(multiValue, index, value); } else { throw new IllegalArgumentException("Can only set positional indices for Lists and Arrays"); } @@ -289,21 +253,17 @@ public static void setValue(final Object iObject, final Object iValue, final int * * @param iObject Multi-value object (array, collection or map) */ - public static Iterable getMultiValueIterable(final Object iObject) { - if (iObject == null) - return null; - - if (iObject instanceof Iterable) - return (Iterable) iObject; - else if (iObject instanceof Collection) - return ((Collection) iObject); - else if (iObject instanceof Map) - return ((Map) iObject).values(); - else if (iObject.getClass().isArray()) - return new IterableObjectArray<>(iObject); - else if (iObject instanceof Iterator) { + public static Iterable getMultiValueIterable(final Object iObject) { + if (iObject == null) return null; + + if (iObject instanceof Iterable iterable) return iterable; + else if (iObject instanceof Collection collection) return collection; + else if (iObject instanceof Map map) return map.values(); + else if (iObject.getClass().isArray()) return new IterableObjectArray<>(iObject); + else if (iObject instanceof Iterator iterator) { + final List temp = new ArrayList<>(); - for (final Iterator it = (Iterator) iObject; it.hasNext(); ) + for (final Iterator it = iterator; it.hasNext(); ) temp.add(it.next()); return temp; } @@ -318,17 +278,12 @@ else if (iObject instanceof Iterator) { * @param iForceConvertRecord allow to force settings to convert RIDs to records while browsing. */ public static Iterable getMultiValueIterable(final Object iObject, final boolean iForceConvertRecord) { - if (iObject == null) - return null; - - if (iObject instanceof Iterable) - return (Iterable) iObject; - else if (iObject instanceof Collection) - return ((Collection) iObject); - else if (iObject instanceof Map) - return ((Map) iObject).values(); - else if (iObject.getClass().isArray()) - return new IterableObjectArray<>(iObject); + if (iObject == null) return null; + + if (iObject instanceof Iterable) return (Iterable) iObject; + else if (iObject instanceof Collection) return ((Collection) iObject); + else if (iObject instanceof Map) return ((Map) iObject).values(); + else if (iObject.getClass().isArray()) return new IterableObjectArray<>(iObject); else if (iObject instanceof Iterator) { final List temp = new ArrayList<>(); for (final Iterator it = (Iterator) iObject; it.hasNext(); ) @@ -346,19 +301,14 @@ else if (iObject instanceof Iterator) { * @param iForceConvertRecord allow to force settings to convert RIDs to records while browsing. */ - public static Iterator getMultiValueIterator(final Object iObject, final boolean iForceConvertRecord) { - if (iObject == null) - return null; + public static Iterator getMultiValueIterator(final Object iObject, final boolean iForceConvertRecord) { + if (iObject == null) return null; - if (iObject instanceof Iterator) - return (Iterator) iObject; + if (iObject instanceof Iterator iterator) return iterator; - if (iObject instanceof Iterable) - return ((Iterable) iObject).iterator(); - if (iObject instanceof Map) - return ((Map) iObject).values().iterator(); - if (iObject.getClass().isArray()) - return new IterableObjectArray<>(iObject).iterator(); + if (iObject instanceof Iterable iterable) return iterable.iterator(); + if (iObject instanceof Map map) return map.values().iterator(); + if (iObject.getClass().isArray()) return new IterableObjectArray<>(iObject).iterator(); return new IterableObject<>(iObject); } @@ -369,19 +319,14 @@ public static Iterator getMultiValueIterator(final Object iObject, final * @param iObject Multi-value object (array, collection or map) */ - public static Iterator getMultiValueIterator(final Object iObject) { - if (iObject == null) - return null; + public static Iterator getMultiValueIterator(final Object iObject) { + if (iObject == null) return null; - if (iObject instanceof Iterator) - return (Iterator) iObject; + if (iObject instanceof Iterator iterator) return iterator; - if (iObject instanceof Iterable) - return ((Iterable) iObject).iterator(); - if (iObject instanceof Map) - return ((Map) iObject).values().iterator(); - if (iObject.getClass().isArray()) - return new IterableObjectArray<>(iObject).iterator(); + if (iObject instanceof Iterable iterable) return iterable.iterator(); + if (iObject instanceof Mapmap) return map.values().iterator(); + if (iObject.getClass().isArray()) return new IterableObjectArray<>(iObject).iterator(); return new IterableObject<>(iObject); } @@ -404,8 +349,7 @@ public static String toString(final Object iObject) { try { final Object e = it.next(); sb.append(e == iObject ? "(this Collection)" : e); - if (it.hasNext()) - sb.append(", "); + if (it.hasNext()) sb.append(", "); } catch (final NoSuchElementException ignore) { // IGNORE THIS } @@ -424,8 +368,7 @@ public static String toString(final Object iObject) { sb.append(e.getKey()); sb.append(":"); sb.append(e.getValue() == iObject ? "(this Map)" : e.getValue()); - if (it.hasNext()) - sb.append(", "); + if (it.hasNext()) sb.append(", "); } catch (final NoSuchElementException ignore) { // IGNORE THIS } @@ -452,19 +395,15 @@ public static Object add(final Object iObject, final Object iToAdd) { if (!(iToAdd instanceof Map) && isMultiValue(iToAdd)) { // COLLECTION - COLLECTION for (final Object o : getMultiValueIterable(iToAdd, false)) { - if (!(o instanceof Map) && isMultiValue(o)) - add(coll, o); - else - coll.add(o); + if (!(o instanceof Map) && isMultiValue(o)) add(coll, o); + else coll.add(o); } } else if (iToAdd != null && iToAdd.getClass().isArray()) { // ARRAY - COLLECTION for (int i = 0; i < Array.getLength(iToAdd); ++i) { final Object o = Array.get(iToAdd, i); - if (!(o instanceof Map) && isMultiValue(o)) - add(coll, o); - else - coll.add(o); + if (!(o instanceof Map) && isMultiValue(o)) add(coll, o); + else coll.add(o); } } else if (iToAdd instanceof Map) { @@ -474,8 +413,7 @@ public static Object add(final Object iObject, final Object iToAdd) { // ITERATOR for (final Iterator it = (Iterator) iToAdd; it.hasNext(); ) coll.add(it.next()); - } else - coll.add(iToAdd); + } else coll.add(iToAdd); } else if (iObject.getClass().isArray()) { // ARRAY - ? @@ -539,19 +477,15 @@ public static Object remove(Object iObject, Object iToRemove, final boolean iAll if (iToRemove instanceof Collection) { // COLLECTION - COLLECTION for (final Object o : (Collection) iToRemove) { - if (isMultiValue(o)) - remove(coll, o, iAllOccurrences); - else - removeFromOCollection(iObject, coll, o, iAllOccurrences); + if (isMultiValue(o)) remove(coll, o, iAllOccurrences); + else removeFromCollection(iObject, coll, o, iAllOccurrences); } } else if (iToRemove != null && iToRemove.getClass().isArray()) { // ARRAY - COLLECTION for (int i = 0; i < Array.getLength(iToRemove); ++i) { final Object o = Array.get(iToRemove, i); - if (isMultiValue(o)) - remove(coll, o, iAllOccurrences); - else - removeFromOCollection(iObject, coll, o, iAllOccurrences); + if (isMultiValue(o)) remove(coll, o, iAllOccurrences); + else removeFromCollection(iObject, coll, o, iAllOccurrences); } } else if (iToRemove instanceof Map) { @@ -560,8 +494,7 @@ public static Object remove(Object iObject, Object iToRemove, final boolean iAll coll.remove(entry.getKey()); } else if (iToRemove instanceof Iterator) { // ITERATOR - if (iToRemove instanceof MultiIterator) - ((MultiIterator) iToRemove).reset(); + if (iToRemove instanceof MultiIterator) ((MultiIterator) iToRemove).reset(); if (iAllOccurrences) { final Collection collection = (Collection) iObject; @@ -574,8 +507,7 @@ public static Object remove(Object iObject, Object iToRemove, final boolean iAll coll.remove(itemToRemove); } } - } else - removeFromOCollection(iObject, coll, iToRemove, iAllOccurrences); + } else removeFromCollection(iObject, coll, iToRemove, iAllOccurrences); } else if (iObject.getClass().isArray()) { // ARRAY - ? @@ -600,8 +532,7 @@ public static Object remove(Object iObject, Object iToRemove, final boolean iAll } } - if (!found) - copy[k++] = o; + if (!found) copy[k++] = o; } } @@ -615,20 +546,18 @@ public static Object remove(Object iObject, Object iToRemove, final boolean iAll } else if (iObject instanceof Map) { ((Map) iObject).remove(iToRemove); - } else - throw new IllegalArgumentException("Object " + iObject + " is not a multi value"); + } else throw new IllegalArgumentException("Object " + iObject + " is not a multi value"); } return iObject; } - protected static void removeFromOCollection(final Object iObject, final Collection coll, final Object iToRemove, + protected static void removeFromCollection(final Object iObject, final Collection coll, final Object iToRemove, final boolean iAllOccurrences) { if (iAllOccurrences && !(iObject instanceof Set)) { // BROWSE THE COLLECTION ONE BY ONE TO REMOVE ALL THE OCCURRENCES coll.removeIf(iToRemove::equals); - } else - coll.remove(iToRemove); + } else coll.remove(iToRemove); } @@ -645,10 +574,8 @@ private static void batchRemove(final Collection coll, final Iterator private static Set prepareBatch(final Iterator it, final int approximateRemainingSize) { final HashSet batch; if (approximateRemainingSize > -1) { - if (approximateRemainingSize > 10000) - batch = new HashSet<>(13400); - else - batch = new HashSet<>((int) (approximateRemainingSize / 0.75)); + if (approximateRemainingSize > 10000) batch = new HashSet<>(13400); + else batch = new HashSet<>((int) (approximateRemainingSize / 0.75)); } else { batch = new HashSet<>(); } @@ -671,8 +598,7 @@ public static T[] array(final Object iValue, final Class iClass } public static T[] array(final Object iValue, final Class iClass, final Callable iCallback) { - if (iValue == null) - return null; + if (iValue == null) return null; final T[] result; @@ -688,8 +614,7 @@ public static T[] array(final Object iValue, final Class iClass for (final Iterator it = (Iterator) getMultiValueIterator(iValue, false); it.hasNext(); ) temp.add((T) convert(it.next(), iCallback)); - if (iClass.equals(Object.class)) - result = (T[]) temp.toArray(); + if (iClass.equals(Object.class)) result = (T[]) temp.toArray(); else // CONVERT THEM result = temp.toArray((T[]) Array.newInstance(iClass, getSize(iValue))); @@ -707,24 +632,20 @@ public static Object convert(final Object iObject, final Callable col1, final Collection col2) { - if (col1.size() != col2.size()) - return false; + if (col1.size() != col2.size()) return false; return col1.containsAll(col2) && col2.containsAll(col1); } public static boolean contains(final Object iObject, final Object iItem) { - if (iObject == null) - return false; + if (iObject == null) return false; - if (iObject instanceof Collection) - return ((Collection) iObject).contains(iItem); + if (iObject instanceof Collection) return ((Collection) iObject).contains(iItem); else if (iObject.getClass().isArray()) { final int size = Array.getLength(iObject); for (int i = 0; i < size; ++i) { final Object item = Array.get(iObject, i); - if (item != null && item.equals(iItem)) - return true; + if (item != null && item.equals(iItem)) return true; } } @@ -732,18 +653,15 @@ else if (iObject.getClass().isArray()) { } public static int indexOf(final Object iObject, final Object iItem) { - if (iObject == null) - return -1; + if (iObject == null) return -1; - if (iObject instanceof List) - return ((List) iObject).indexOf(iItem); + if (iObject instanceof List) return ((List) iObject).indexOf(iItem); else if (iObject.getClass().isArray()) { final int size = Array.getLength(iObject); for (int i = 0; i < size; ++i) { final Object item = Array.get(iObject, i); - if (item != null && item.equals(iItem)) - return i; + if (item != null && item.equals(iItem)) return i; } } @@ -751,10 +669,8 @@ else if (iObject.getClass().isArray()) { } public static Object toSet(final Object o) { - if (o instanceof Set) - return o; - else if (o instanceof Collection) - return new HashSet((Collection) o); + if (o instanceof Set) return o; + else if (o instanceof Collection) return new HashSet((Collection) o); else if (o instanceof Map) { final Collection values = ((Map) o).values(); return values instanceof Set ? values : new HashSet(values); diff --git a/engine/src/main/java/com/arcadedb/query/sql/function/SQLFunctionFactoryTemplate.java b/engine/src/main/java/com/arcadedb/query/sql/function/SQLFunctionFactoryTemplate.java index 3590cf2667..9a0efef452 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/function/SQLFunctionFactoryTemplate.java +++ b/engine/src/main/java/com/arcadedb/query/sql/function/SQLFunctionFactoryTemplate.java @@ -62,8 +62,8 @@ public SQLFunction getFunctionInstance(final String name) throws CommandExecutio if (obj == null) return null; - if (obj instanceof SQLFunction) - return (SQLFunction) obj; + if (obj instanceof SQLFunction sqlFunction) + return sqlFunction; else { // it's a class final Class typez = (Class) obj; diff --git a/engine/src/main/java/com/arcadedb/query/sql/function/SQLFunctionReflectionFactory.java b/engine/src/main/java/com/arcadedb/query/sql/function/SQLFunctionReflectionFactory.java index 2d525d265f..169dec3b27 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/function/SQLFunctionReflectionFactory.java +++ b/engine/src/main/java/com/arcadedb/query/sql/function/SQLFunctionReflectionFactory.java @@ -40,7 +40,8 @@ public SQLFunctionReflectionFactory(final DefaultSQLFunctionFactory factory) { } public void register(final String prefix, final Class clazz) { - final Map> methodsMap = Arrays.stream(clazz.getMethods()).filter(m -> Modifier.isStatic(m.getModifiers())) + final Map> methodsMap = Arrays.stream(clazz.getMethods()) + .filter(m -> Modifier.isStatic(m.getModifiers())) .collect(Collectors.groupingBy(Method::getName)); for (final Map.Entry> entry : methodsMap.entrySet()) { diff --git a/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionAstar.java b/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionAstar.java index 8ee52a36b9..154e761710 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionAstar.java +++ b/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionAstar.java @@ -45,21 +45,22 @@ public class SQLFunctionAstar extends SQLFunctionHeuristicPathFinderAbstract { public static final String NAME = "astar"; - private String paramWeightFieldName = "weight"; - private long currentDepth = 0; - protected final Set closedSet = new HashSet(); - protected final Map cameFrom = new HashMap(); + private String paramWeightFieldName = "weight"; + private long currentDepth = 0; + protected final Set closedSet = new HashSet(); + protected final Map cameFrom = new HashMap(); protected final Map gScore = new HashMap(); protected final Map fScore = new HashMap(); - protected final PriorityQueue open = new PriorityQueue(1, (nodeA, nodeB) -> Double.compare(fScore.get(nodeA), fScore.get(nodeB))); + protected final PriorityQueue open = new PriorityQueue(1, + (nodeA, nodeB) -> Double.compare(fScore.get(nodeA), fScore.get(nodeB))); public SQLFunctionAstar() { super(NAME); } - public LinkedList execute(final Object iThis, final Identifiable iCurrentRecord, final Object iCurrentResult, final Object[] iParams, - final CommandContext iContext) { + public LinkedList execute(final Object iThis, final Identifiable iCurrentRecord, final Object iCurrentResult, + final Object[] iParams, final CommandContext iContext) { context = iContext; final SQLFunctionAstar context = this; @@ -67,46 +68,41 @@ public LinkedList execute(final Object iThis, final Identifiable iCurren Object source = iParams[0]; if (MultiValue.isMultiValue(source)) { - if (MultiValue.getSize(source) > 1) - throw new IllegalArgumentException("Only one sourceVertex is allowed"); + if (MultiValue.getSize(source) > 1) throw new IllegalArgumentException("Only one sourceVertex is allowed"); source = MultiValue.getFirstValue(source); if (source instanceof Result && ((Result) source).isElement()) { source = ((Result) source).getElement().get(); } } - if (record != null) - source = record.get((String) source); + if (record != null) source = record.get((String) source); if (source instanceof Identifiable) { final Document elem = (Document) ((Identifiable) source).getRecord(); - if (!(elem instanceof Vertex)) - throw new IllegalArgumentException("The sourceVertex must be a vertex record"); + if (!(elem instanceof Vertex)) throw new IllegalArgumentException("The sourceVertex must be a vertex record"); paramSourceVertex = (Vertex) elem; } else { throw new IllegalArgumentException("The sourceVertex must be a vertex record"); } - Object dest = iParams[1]; - if (MultiValue.isMultiValue(dest)) { - if (MultiValue.getSize(dest) > 1) - throw new IllegalArgumentException("Only one destinationVertex is allowed"); - dest = MultiValue.getFirstValue(dest); - if (dest instanceof Result && ((Result) dest).isElement()) { - dest = ((Result) dest).getElement().get(); - } - } +Object dest = iParams[1]; +if (MultiValue.isMultiValue(dest)) { + if (MultiValue.getSize(dest) > 1) throw new IllegalArgumentException("Only one destinationVertex is allowed"); + dest = MultiValue.getFirstValue(dest); + if (dest instanceof Result result && result.isElement()) { + dest = result.getElement().get(); + } +} - if (record != null) - dest = record.get((String) dest); +if (record != null) dest = record.get((String) dest); if (record != null) dest = record.get((String) dest); - if (dest instanceof Identifiable) { - final Document elem = (Document) ((Identifiable) dest).getRecord(); - if (!(elem instanceof Vertex)) + if (dest instanceof Identifiable identifiable) { + final Document elem = (Document) identifiable.getRecord(); + if (!(elem instanceof Vertex vertex)) { throw new IllegalArgumentException("The destinationVertex must be a vertex record"); - - paramDestinationVertex = (Vertex) elem; + } + paramDestinationVertex = vertex; } else { throw new IllegalArgumentException("The destinationVertex must be a vertex record"); } @@ -194,11 +190,9 @@ private Vertex getNeighbor(final Vertex current, final Edge neighborEdge, final } private Vertex toVertex(Identifiable outVertex) { - if (outVertex == null) - return null; + if (outVertex == null) return null; - if (!(outVertex instanceof Record)) - outVertex = outVertex.getRecord(); + if (!(outVertex instanceof Record)) outVertex = outVertex.getRecord(); return (Vertex) outVertex; } @@ -210,8 +204,7 @@ protected Set getNeighborEdges(final Vertex node) { if (node != null) { for (final Edge v : node.getEdges(paramDirection, paramEdgeTypeNames)) { final Edge ov = v; - if (ov != null) - neighbors.add(ov); + if (ov != null) neighbors.add(ov); } } return neighbors; @@ -232,7 +225,8 @@ private void bindAdditionalParams(final Object additionalParams, final SQLFuncti context.paramVertexAxisNames = stringArray(mapParams.get(SQLFunctionAstar.PARAM_VERTEX_AXIS_NAMES)); if (mapParams.get(SQLFunctionAstar.PARAM_DIRECTION) != null) { if (mapParams.get(SQLFunctionAstar.PARAM_DIRECTION) instanceof String) { - context.paramDirection = Vertex.DIRECTION.valueOf(stringOrDefault(mapParams.get(SQLFunctionAstar.PARAM_DIRECTION), "OUT").toUpperCase(Locale.ENGLISH)); + context.paramDirection = Vertex.DIRECTION.valueOf( + stringOrDefault(mapParams.get(SQLFunctionAstar.PARAM_DIRECTION), "OUT").toUpperCase(Locale.ENGLISH)); } else { context.paramDirection = (Vertex.DIRECTION) mapParams.get(SQLFunctionAstar.PARAM_DIRECTION); } @@ -240,7 +234,8 @@ private void bindAdditionalParams(final Object additionalParams, final SQLFuncti context.paramParallel = booleanOrDefault(mapParams.get(SQLFunctionAstar.PARAM_PARALLEL), false); context.paramMaxDepth = longOrDefault(mapParams.get(SQLFunctionAstar.PARAM_MAX_DEPTH), context.paramMaxDepth); - context.paramEmptyIfMaxDepth = booleanOrDefault(mapParams.get(SQLFunctionAstar.PARAM_EMPTY_IF_MAX_DEPTH), context.paramEmptyIfMaxDepth); + context.paramEmptyIfMaxDepth = booleanOrDefault(mapParams.get(SQLFunctionAstar.PARAM_EMPTY_IF_MAX_DEPTH), + context.paramEmptyIfMaxDepth); context.paramTieBreaker = booleanOrDefault(mapParams.get(SQLFunctionAstar.PARAM_TIE_BREAKER), context.paramTieBreaker); context.paramDFactor = doubleOrDefault(mapParams.get(SQLFunctionAstar.PARAM_D_FACTOR), context.paramDFactor); if (mapParams.get(SQLFunctionAstar.PARAM_HEURISTIC_FORMULA) != null) { @@ -278,11 +273,8 @@ protected double getDistance(final Vertex node, final Vertex parent, final Verte } if (e != null) { final Object fieldValue = e.get(paramWeightFieldName); - if (fieldValue != null) - if (fieldValue instanceof Float) - return (Float) fieldValue; - else if (fieldValue instanceof Number) - return ((Number) fieldValue).doubleValue(); + if (fieldValue != null) if (fieldValue instanceof Float) return (Float) fieldValue; + else if (fieldValue instanceof Number) return ((Number) fieldValue).doubleValue(); } return MIN; @@ -291,11 +283,8 @@ else if (fieldValue instanceof Number) protected double getDistance(final Edge edge) { if (edge != null) { final Object fieldValue = edge.get(paramWeightFieldName); - if (fieldValue != null) - if (fieldValue instanceof Float) - return (Float) fieldValue; - else if (fieldValue instanceof Number) - return ((Number) fieldValue).doubleValue(); + if (fieldValue != null) if (fieldValue instanceof Float) return (Float) fieldValue; + else if (fieldValue instanceof Number) return ((Number) fieldValue).doubleValue(); } return MIN; @@ -317,8 +306,7 @@ protected double getHeuristicCost(final Vertex node, Vertex parent, final Vertex final double g = doubleOrDefault(target.get(paramVertexAxisNames[0]), 0.0); hresult = getSimpleHeuristicCost(n, g, paramDFactor); } else if (paramVertexAxisNames.length == 2) { - if (parent == null) - parent = node; + if (parent == null) parent = node; final double sx = doubleOrDefault(paramSourceVertex.get(paramVertexAxisNames[0]), 0); final double sy = doubleOrDefault(paramSourceVertex.get(paramVertexAxisNames[1]), 0); final double nx = doubleOrDefault(node.get(paramVertexAxisNames[0]), 0); @@ -360,14 +348,10 @@ protected double getHeuristicCost(final Vertex node, Vertex parent, final Vertex final Double c = doubleOrDefault(node.get(paramVertexAxisNames[i]), 0); final Double g = doubleOrDefault(target.get(paramVertexAxisNames[i]), 0); final Double p = doubleOrDefault(parent.get(paramVertexAxisNames[i]), 0); - if (s != null) - sList.put(paramVertexAxisNames[i], s); - if (c != null) - cList.put(paramVertexAxisNames[i], s); - if (g != null) - gList.put(paramVertexAxisNames[i], g); - if (p != null) - pList.put(paramVertexAxisNames[i], p); + if (s != null) sList.put(paramVertexAxisNames[i], s); + if (c != null) cList.put(paramVertexAxisNames[i], s); + if (g != null) gList.put(paramVertexAxisNames[i], g); + if (p != null) pList.put(paramVertexAxisNames[i], p); } switch (paramHeuristicFormula) { case MANHATTAN: diff --git a/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionDijkstra.java b/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionDijkstra.java index 02c2b92633..5ad99bddbc 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionDijkstra.java +++ b/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionDijkstra.java @@ -41,20 +41,20 @@ public SQLFunctionDijkstra() { super(NAME); } - public LinkedList execute(final Object iThis, final Identifiable iCurrentRecord, final Object iCurrentResult, final Object[] iParams, - final CommandContext iContext) { - return new SQLFunctionAstar().execute(this, iCurrentRecord, iCurrentResult, toAStarParams(iParams), iContext); + public LinkedList execute(final Object thisObj, final Identifiable currentRecord, final Object currentResult, final Object[] params, + final CommandContext context) { + return new SQLFunctionAstar().execute(thisObj, currentRecord, currentResult, toAStarParams(params), context); } - private Object[] toAStarParams(final Object[] iParams) { + private Object[] toAStarParams(final Object[] params) { final Object[] result = new Object[4]; - result[0] = iParams[0]; - result[1] = iParams[1]; - result[2] = iParams[2]; - final Map options = new HashMap(); + result[0] = params[0]; + result[1] = params[1]; + result[2] = params[2]; + final Map options = new HashMap<>(); options.put("emptyIfMaxDepth", true); - if (iParams.length > 3) { - options.put("direction", iParams[3]); + if (params.length > 3) { + options.put("direction", params[3]); } result[3] = options; return result; diff --git a/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionMove.java b/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionMove.java index bd3f1a25ef..2b8b8d3c50 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionMove.java +++ b/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionMove.java @@ -50,7 +50,7 @@ public Object execute(final Object iThis, final Identifiable iCurrentRecord, fin final String[] labels; if (iParameters != null && iParameters.length > 0 && iParameters[0] != null) - labels = MultiValue.array(iParameters, String.class, iArgument -> FileUtils.getStringContent(iArgument)); + labels = MultiValue.array(iParameters, String.class, FileUtils::getStringContent); else labels = null; @@ -60,30 +60,30 @@ public Object execute(final Object iThis, final Identifiable iCurrentRecord, fin protected Object v2v(final Database graph, final Identifiable iRecord, final Vertex.DIRECTION iDirection, final String[] iLabels) { if (iRecord != null) { final Document rec = (Document) iRecord.getRecord(); - if (rec instanceof Vertex) - return ((Vertex) rec).getVertices(iDirection, iLabels); + if (rec instanceof Vertex vertex) + return vertex.getVertices(iDirection, iLabels); } return null; } protected Object v2e(final Database graph, final Identifiable iRecord, final Vertex.DIRECTION iDirection, final String[] iLabels) { final Document rec = (Document) iRecord.getRecord(); - if (rec instanceof Vertex) - return ((Vertex) rec).getEdges(iDirection, iLabels); + if (rec instanceof Vertex vertex) + return vertex.getEdges(iDirection, iLabels); return null; } protected Object e2v(final Database graph, final Identifiable iRecord, final Vertex.DIRECTION iDirection, final String[] iLabels) { final Document rec = (Document) iRecord.getRecord(); - if (rec instanceof Edge) { + if (rec instanceof Edge edge) { if (iDirection == Vertex.DIRECTION.BOTH) { - final List results = new ArrayList(); - results.add(((Edge) rec).getOutVertex()); - results.add(((Edge) rec).getInVertex()); + var results = new ArrayList(); + results.add(edge.getOutVertex()); + results.add(edge.getInVertex()); return results; } - return ((Edge) rec).getVertex(iDirection); + return edge.getVertex(iDirection); } return null; diff --git a/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionMoveFiltered.java b/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionMoveFiltered.java index 998b0cf793..8bf1b8c9f6 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionMoveFiltered.java +++ b/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionMoveFiltered.java @@ -42,7 +42,7 @@ public Object execute(final Object iThis, final Identifiable iCurrentRecord, fin final Iterable iPossibleResults, final CommandContext iContext) { final String[] labels; if (iParameters != null && iParameters.length > 0 && iParameters[0] != null) - labels = MultiValue.array(iParameters, String.class, iArgument -> FileUtils.getStringContent(iArgument)); + labels = MultiValue.array(iParameters, String.class, FileUtils::getStringContent); else labels = null; diff --git a/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionPathFinder.java b/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionPathFinder.java index f761178588..8404fc67a1 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionPathFinder.java +++ b/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionPathFinder.java @@ -35,7 +35,7 @@ public abstract class SQLFunctionPathFinder extends SQLFunctionMathAbstract { protected Map predecessors; protected Map distance; - protected Vertex paramSourceVertex; + protected Vertex paramSourceVertex; protected Vertex paramDestinationVertex; protected final Vertex.DIRECTION paramDirection = Vertex.DIRECTION.OUT; protected CommandContext context; @@ -48,9 +48,9 @@ public SQLFunctionPathFinder(final String iName) { protected LinkedList execute(final CommandContext iContext) { context = iContext; - unSettledNodes = new HashSet(); - distance = new HashMap(); - predecessors = new HashMap(); + unSettledNodes = new HashSet<>(); + distance = new HashMap<>(); + predecessors = new HashMap<>(); distance.put(paramSourceVertex.getIdentity(), MIN); unSettledNodes.add(paramSourceVertex); @@ -64,12 +64,9 @@ protected LinkedList execute(final CommandContext iContext) { unSettledNodes.remove(node); findMinimalDistances(node); - if (distance.size() > maxDistances) - maxDistances = distance.size(); - if (unSettledNodes.size() > maxUnSettled) - maxUnSettled = unSettledNodes.size(); - if (predecessors.size() > maxPredecessors) - maxPredecessors = predecessors.size(); + if (distance.size() > maxDistances) maxDistances = distance.size(); + if (unSettledNodes.size() > maxUnSettled) maxUnSettled = unSettledNodes.size(); + if (predecessors.size() > maxPredecessors) maxPredecessors = predecessors.size(); if (!isVariableEdgeWeight() && distance.containsKey(paramDestinationVertex.getIdentity())) // FOUND @@ -97,8 +94,7 @@ public LinkedList getPath() { final LinkedList path = new LinkedList(); Vertex step = paramDestinationVertex; // Check if a path exists - if (predecessors.get(step.getIdentity()) == null) - return null; + if (predecessors.get(step.getIdentity()) == null) return null; path.add(step); while (predecessors.get(step.getIdentity()) != null) { @@ -139,8 +135,7 @@ protected Set getNeighbors(final Vertex node) { if (node != null) { for (final Vertex v : node.getVertices(paramDirection)) { final Vertex ov = v; - if (ov != null && isNotSettled(ov)) - neighbors.add(ov); + if (ov != null && isNotSettled(ov)) neighbors.add(ov); } } return neighbors; @@ -167,8 +162,7 @@ protected boolean continueTraversing() { } protected float getShortestDistance(final Vertex destination) { - if (destination == null) - return Float.MAX_VALUE; + if (destination == null) return Float.MAX_VALUE; final Float d = distance.get(destination.getIdentity()); return d == null ? Float.MAX_VALUE : d; diff --git a/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionShortestPath.java b/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionShortestPath.java index 745bd6aa81..1eb164d813 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionShortestPath.java +++ b/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLFunctionShortestPath.java @@ -47,7 +47,7 @@ public SQLFunctionShortestPath() { super(NAME); } - private static class OShortestPathContext { + private static class ShortestPathContext { Vertex sourceVertex; Vertex destinationVertex; Vertex.DIRECTION directionLeft = Vertex.DIRECTION.BOTH; @@ -59,14 +59,14 @@ private static class OShortestPathContext { ArrayDeque queueLeft = new ArrayDeque<>(); ArrayDeque queueRight = new ArrayDeque<>(); - final Set leftVisited = new HashSet(); - final Set rightVisited = new HashSet(); - - final Map previouses = new HashMap(); - final Map nexts = new HashMap(); + final Set leftVisited = new HashSet<>(); + final Set rightVisited = new HashSet<>(); + final Map previouses = new HashMap<>(); + final Map nexts = new HashMap<>(); Vertex current; Vertex currentRight; + public Integer maxDepth; /** * option that decides whether or not to return the edge information @@ -74,157 +74,140 @@ private static class OShortestPathContext { public Boolean edge; } - public List execute(final Object iThis, final Identifiable iCurrentRecord, final Object iCurrentResult, final Object[] iParams, - final CommandContext iContext) { + public List execute(final Object iThis, final Identifiable currentRecord, final Object currentResult, final Object[] params, + final CommandContext context) { - final OShortestPathContext context = new OShortestPathContext(); + final ShortestPathContext shortestPathContext = new ShortestPathContext(); - Object source = iParams[0]; + Object source = params[0]; if (MultiValue.isMultiValue(source)) { - if (MultiValue.getSize(source) > 1) - throw new IllegalArgumentException("Only one sourceVertex is allowed"); + if (MultiValue.getSize(source) > 1) throw new IllegalArgumentException("Only one sourceVertex is allowed"); source = MultiValue.getFirstValue(source); - if (source instanceof Result && ((Result) source).isElement()) { - source = ((Result) source).getElement().get(); + if (source instanceof Result result && result.isElement()) { + source = result.getElement().get(); } } // source = record.get((String) source); - if (source instanceof Identifiable) { - final Document elem = (Document) ((Identifiable) source).getRecord(); - if (!(elem instanceof Vertex)) - throw new IllegalArgumentException("The sourceVertex must be a vertex record"); + if (source instanceof Identifiable identifiable) { + final Document elem = (Document) identifiable.getRecord(); + if (!(elem instanceof Vertex)) throw new IllegalArgumentException("The sourceVertex must be a vertex record"); - context.sourceVertex = (Vertex) elem; + shortestPathContext.sourceVertex = (Vertex) elem; } else { throw new IllegalArgumentException("The sourceVertex must be a vertex record"); } - Object dest = iParams[1]; + Object dest = params[1]; if (MultiValue.isMultiValue(dest)) { - if (MultiValue.getSize(dest) > 1) - throw new IllegalArgumentException("Only one destinationVertex is allowed"); + if (MultiValue.getSize(dest) > 1) throw new IllegalArgumentException("Only one destinationVertex is allowed"); dest = MultiValue.getFirstValue(dest); - if (dest instanceof Result && ((Result) dest).isElement()) { - dest = ((Result) dest).getElement().get(); + if (dest instanceof Result result && result.isElement()) { + dest = result.getElement().get(); } } // dest = record.get((String) dest); - if (dest instanceof Identifiable) { - final Document elem = (Document) ((Identifiable) dest).getRecord(); - if (!(elem instanceof Vertex)) - throw new IllegalArgumentException("The destinationVertex must be a vertex record"); + if (dest instanceof Identifiable identifiable1) { + final Document elem = (Document) identifiable1.getRecord(); + if (!(elem instanceof Vertex vertex)) throw new IllegalArgumentException("The destinationVertex must be a vertex record"); - context.destinationVertex = (Vertex) elem; + shortestPathContext.destinationVertex = vertex; } else { throw new IllegalArgumentException("The destinationVertex must be a vertex record"); } - if (context.sourceVertex.equals(context.destinationVertex)) { - final List result = new ArrayList(1); - result.add(context.destinationVertex.getIdentity()); + if (shortestPathContext.sourceVertex.equals(shortestPathContext.destinationVertex)) { + final List result = new ArrayList<>(1); + result.add(shortestPathContext.destinationVertex.getIdentity()); return result; } - if (iParams.length > 2 && iParams[2] != null) { - context.directionLeft = Vertex.DIRECTION.valueOf(iParams[2].toString().toUpperCase(Locale.ENGLISH)); + if (params.length > 2 && params[2] != null) { + shortestPathContext.directionLeft = Vertex.DIRECTION.valueOf(params[2].toString().toUpperCase(Locale.ENGLISH)); } - if (context.directionLeft == Vertex.DIRECTION.OUT) { - context.directionRight = Vertex.DIRECTION.IN; - } else if (context.directionLeft == Vertex.DIRECTION.IN) { - context.directionRight = Vertex.DIRECTION.OUT; + if (shortestPathContext.directionLeft == Vertex.DIRECTION.OUT) { + shortestPathContext.directionRight = Vertex.DIRECTION.IN; + } else if (shortestPathContext.directionLeft == Vertex.DIRECTION.IN) { + shortestPathContext.directionRight = Vertex.DIRECTION.OUT; } - context.edgeType = null; - if (iParams.length > 3) { - context.edgeType = iParams[3] == null ? null : "" + iParams[3]; + shortestPathContext.edgeType = null; + if (params.length > 3) { + shortestPathContext.edgeType = params[3] == null ? null : "" + params[3]; } - context.edgeTypeParam = null; - if (iParams.length > 3 && iParams[3] != null) { - if (iParams[3] instanceof List) { - final List list = (List) iParams[3]; - context.edgeTypeParam = list.toArray(new String[list.size()]); - } else - context.edgeTypeParam = new String[] { context.edgeType }; + shortestPathContext.edgeTypeParam = null; + if (params.length > 3 && params[3] != null) { + if (params[3] instanceof List list) { + shortestPathContext.edgeTypeParam = list.toArray(new String[0]); + } else shortestPathContext.edgeTypeParam = new String[] { shortestPathContext.edgeType }; } - if (iParams.length > 4) { - bindAdditionalParams(iParams[4], context); + if (params.length > 4) { + bindAdditionalParams(params[4], shortestPathContext); } - context.queueLeft.add(context.sourceVertex); - context.leftVisited.add(context.sourceVertex.getIdentity()); + shortestPathContext.queueLeft.add(shortestPathContext.sourceVertex); + shortestPathContext.leftVisited.add(shortestPathContext.sourceVertex.getIdentity()); - context.queueRight.add(context.destinationVertex); - context.rightVisited.add(context.destinationVertex.getIdentity()); + shortestPathContext.queueRight.add(shortestPathContext.destinationVertex); + shortestPathContext.rightVisited.add(shortestPathContext.destinationVertex.getIdentity()); int depth = 1; while (true) { - if (context.maxDepth != null && context.maxDepth <= depth) { + if (shortestPathContext.maxDepth != null && shortestPathContext.maxDepth <= depth) { break; } - if (context.queueLeft.isEmpty() || context.queueRight.isEmpty()) - break; + if (shortestPathContext.queueLeft.isEmpty() || shortestPathContext.queueRight.isEmpty()) break; - if (Thread.interrupted()) - throw new CommandExecutionException("The shortestPath() function has been interrupted"); + if (Thread.interrupted()) throw new CommandExecutionException("The shortestPath() function has been interrupted"); List neighborIdentity; - if (context.queueLeft.size() <= context.queueRight.size()) { + if (shortestPathContext.queueLeft.size() <= shortestPathContext.queueRight.size()) { // START EVALUATING FROM LEFT - neighborIdentity = walkLeft(context); - if (neighborIdentity != null) - return neighborIdentity; + neighborIdentity = walkLeft(shortestPathContext); + if (neighborIdentity != null) return neighborIdentity; depth++; - if (context.maxDepth != null && context.maxDepth <= depth) { + if (shortestPathContext.maxDepth != null && shortestPathContext.maxDepth <= depth) { break; } - if (context.queueLeft.isEmpty()) - break; + if (shortestPathContext.queueLeft.isEmpty()) break; - neighborIdentity = walkRight(context); - if (neighborIdentity != null) - return neighborIdentity; + neighborIdentity = walkRight(shortestPathContext); + if (neighborIdentity != null) return neighborIdentity; } else { // START EVALUATING FROM RIGHT - neighborIdentity = walkRight(context); - if (neighborIdentity != null) - return neighborIdentity; + neighborIdentity = walkRight(shortestPathContext); + if (neighborIdentity != null) return neighborIdentity; depth++; - if (context.maxDepth != null && context.maxDepth <= depth) { + if (shortestPathContext.maxDepth != null && shortestPathContext.maxDepth <= depth) { break; } - if (context.queueRight.isEmpty()) - break; + if (shortestPathContext.queueRight.isEmpty()) break; - neighborIdentity = walkLeft(context); - if (neighborIdentity != null) - return neighborIdentity; + neighborIdentity = walkLeft(shortestPathContext); + if (neighborIdentity != null) return neighborIdentity; } depth++; } - return new ArrayList(); + return new ArrayList<>(); } - private void bindAdditionalParams(final Object additionalParams, final OShortestPathContext context) { - if (additionalParams == null) - return; + private void bindAdditionalParams(final Object additionalParams, final ShortestPathContext context) { + if (additionalParams == null) return; Map mapParams = null; - if (additionalParams instanceof Map) - mapParams = (Map) additionalParams; - else if (additionalParams instanceof Identifiable) - mapParams = ((Document) ((Identifiable) additionalParams).getRecord()).toMap(); + if (additionalParams instanceof Map map) mapParams = map; + else if (additionalParams instanceof Identifiable identifiable) mapParams = identifiable.getRecord().asDocument().toMap(); if (mapParams != null) { context.maxDepth = integer(mapParams.get("maxDepth")); @@ -234,15 +217,13 @@ else if (additionalParams instanceof Identifiable) } private Integer integer(final Object fromObject) { - if (fromObject == null) - return null; + if (fromObject == null) return null; - if (fromObject instanceof Number) - return ((Number) fromObject).intValue(); + if (fromObject instanceof Number number) return number.intValue(); - if (fromObject instanceof String) { + if (fromObject instanceof String string) { try { - return Integer.parseInt(fromObject.toString()); + return Integer.parseInt(string); } catch (final NumberFormatException ignore) { } } @@ -255,15 +236,13 @@ private Integer integer(final Object fromObject) { * @author Thomas Young (YJJThomasYoung@hotmail.com) */ private Boolean toBoolean(final Object fromObject) { - if (fromObject == null) - return null; + if (fromObject == null) return null; - if (fromObject instanceof Boolean) - return (Boolean) fromObject; + if (fromObject instanceof Boolean bool) return bool; - if (fromObject instanceof String) { + if (fromObject instanceof String string) { try { - return Boolean.parseBoolean(fromObject.toString()); + return Boolean.parseBoolean(string); } catch (final NumberFormatException ignore) { } } @@ -281,7 +260,8 @@ private Boolean toBoolean(final Object fromObject) { * * @author Thomas Young (YJJThomasYoung@hotmail.com) */ - private Pair, Iterable> getVerticesAndEdges(final Vertex srcVertex, final Vertex.DIRECTION direction, final String... types) { + private Pair, Iterable> getVerticesAndEdges(final Vertex srcVertex, final Vertex.DIRECTION direction, + final String... types) { if (direction == Vertex.DIRECTION.BOTH) { final MultiIterator vertexIterator = new MultiIterator<>(); final MultiIterator edgeIterator = new MultiIterator<>(); @@ -317,7 +297,7 @@ public String getSyntax() { return "shortestPath(, , [, [ ]])"; } - protected List walkLeft(final SQLFunctionShortestPath.OShortestPathContext context) { + protected List walkLeft(final ShortestPathContext context) { final ArrayDeque nextLevelQueue = new ArrayDeque<>(); if (!Boolean.TRUE.equals(context.edge)) { while (!context.queueLeft.isEmpty()) { @@ -330,8 +310,7 @@ protected List walkLeft(final SQLFunctionShortestPath.OShortestPathContext neighbors = context.current.getVertices(context.directionLeft, context.edgeTypeParam); } for (final Vertex neighbor : neighbors) { - final Vertex v = neighbor; - final RID neighborIdentity = v.getIdentity(); + final RID neighborIdentity = neighbor.getIdentity(); if (context.rightVisited.contains(neighborIdentity)) { context.previouses.put(neighborIdentity, context.current.getIdentity()); @@ -340,7 +319,7 @@ protected List walkLeft(final SQLFunctionShortestPath.OShortestPathContext if (!context.leftVisited.contains(neighborIdentity)) { context.previouses.put(neighborIdentity, context.current.getIdentity()); - nextLevelQueue.offer(v); + nextLevelQueue.offer(neighbor); context.leftVisited.add(neighborIdentity); } @@ -382,7 +361,7 @@ protected List walkLeft(final SQLFunctionShortestPath.OShortestPathContext return null; } - protected List walkRight(final SQLFunctionShortestPath.OShortestPathContext context) { + protected List walkRight(final ShortestPathContext context) { final ArrayDeque nextLevelQueue = new ArrayDeque<>(); if (!Boolean.TRUE.equals(context.edge)) { while (!context.queueRight.isEmpty()) { @@ -395,8 +374,7 @@ protected List walkRight(final SQLFunctionShortestPath.OShortestPathContext neighbors = context.currentRight.getVertices(context.directionRight, context.edgeTypeParam); } for (final Vertex neighbor : neighbors) { - final Vertex v = neighbor; - final RID neighborIdentity = v.getIdentity(); + final RID neighborIdentity = neighbor.getIdentity(); if (context.leftVisited.contains(neighborIdentity)) { context.nexts.put(neighborIdentity, context.currentRight.getIdentity()); @@ -406,7 +384,7 @@ protected List walkRight(final SQLFunctionShortestPath.OShortestPathContext context.nexts.put(neighborIdentity, context.currentRight.getIdentity()); - nextLevelQueue.offer(v); + nextLevelQueue.offer(neighbor); context.rightVisited.add(neighborIdentity); } diff --git a/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLHeuristicFormula.java b/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLHeuristicFormula.java index 2d44012e7d..9cae46a4d5 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLHeuristicFormula.java +++ b/engine/src/main/java/com/arcadedb/query/sql/function/graph/SQLHeuristicFormula.java @@ -24,5 +24,9 @@ * @author Saeed Tabrizi (saeed a_t nowcando.com) */ public enum SQLHeuristicFormula { - MANHATTAN, MAXAXIS, DIAGONAL, EUCLIDEAN, EUCLIDEANNOSQR + MANHATTAN, + MAXAXIS, + DIAGONAL, + EUCLIDEAN, + EUCLIDEANNOSQR } diff --git a/engine/src/main/java/com/arcadedb/query/sql/function/misc/SQLFunctionUUID.java b/engine/src/main/java/com/arcadedb/query/sql/function/misc/SQLFunctionUUID.java index 1104dd3648..21a42f7501 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/function/misc/SQLFunctionUUID.java +++ b/engine/src/main/java/com/arcadedb/query/sql/function/misc/SQLFunctionUUID.java @@ -45,17 +45,8 @@ public Object execute(final Object iThis, final Identifiable iCurrentRecord, fin return UUID.randomUUID().toString(); } - @Override - public boolean aggregateResults() { - return false; - } - public String getSyntax() { return "uuid()"; } - @Override - public Object getResult() { - return null; - } } diff --git a/engine/src/main/java/com/arcadedb/query/sql/function/misc/SQLFunctionVersion.java b/engine/src/main/java/com/arcadedb/query/sql/function/misc/SQLFunctionVersion.java index 513835b38d..f75f9430c1 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/function/misc/SQLFunctionVersion.java +++ b/engine/src/main/java/com/arcadedb/query/sql/function/misc/SQLFunctionVersion.java @@ -46,17 +46,9 @@ public Object execute(final Object iThis, final Identifiable iCurrentRecord, fin return Constants.getVersion(); } - @Override - public boolean aggregateResults() { - return false; - } public String getSyntax() { return "version()"; } - @Override - public Object getResult() { - return null; - } } diff --git a/engine/src/main/java/com/arcadedb/query/sql/function/time/SQLFunctionDuration.java b/engine/src/main/java/com/arcadedb/query/sql/function/time/SQLFunctionDuration.java index 2a5fd853b6..108e6864ef 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/function/time/SQLFunctionDuration.java +++ b/engine/src/main/java/com/arcadedb/query/sql/function/time/SQLFunctionDuration.java @@ -43,20 +43,19 @@ public SQLFunctionDuration() { super(NAME); } - public Object execute(final Object iThis, final Identifiable iCurrentRecord, final Object iCurrentResult, final Object[] iParams, - final CommandContext iContext) { - if (iParams.length != 2) - throw new IllegalArgumentException("duration() function expected 2 parameters: amount and time-unit"); + public Object execute(final Object thisObject, final Identifiable currentRecord, final Object currentResult, + final Object[] params, final CommandContext context) { + if (params.length != 2) throw new IllegalArgumentException("duration() function expected 2 parameters: amount and time-unit"); - long amount; - if (iParams[0] instanceof Number) - amount = ((Number) iParams[0]).longValue(); - else if (iParams[0] instanceof String) - amount = Long.parseLong(iParams[0].toString()); - else - throw new IllegalArgumentException("amount '" + iParams[0] + "' not a number or a string"); + long amount = getAmount(params[0]); - return Duration.of(amount, DateUtils.parsePrecision(iParams[1].toString())); + return Duration.of(amount, DateUtils.parsePrecision(params[1].toString())); + } + + private static long getAmount(Object param) { + if (param instanceof Number number) return number.longValue(); + else if (param instanceof String string) return Long.parseLong(string); + else throw new IllegalArgumentException("amount '" + param + "' not a number or a string"); } public String getSyntax() { diff --git a/engine/src/main/java/com/arcadedb/query/sql/function/time/SQLFunctionSysdate.java b/engine/src/main/java/com/arcadedb/query/sql/function/time/SQLFunctionSysdate.java index 1f25e10296..aa0b7a64bb 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/function/time/SQLFunctionSysdate.java +++ b/engine/src/main/java/com/arcadedb/query/sql/function/time/SQLFunctionSysdate.java @@ -43,17 +43,17 @@ public SQLFunctionSysdate() { super(NAME); } - public Object execute(final Object iThis, final Identifiable iCurrentRecord, final Object iCurrentResult, final Object[] iParams, - final CommandContext iContext) { + public Object execute(final Object thisObject, final Identifiable currentRecord, final Object currentResult, final Object[] params, + final CommandContext context) { final LocalDateTime now = LocalDateTime.now(); Object result = now; - if (iParams.length > 0) { - if (iParams.length > 1) - result = now.atZone(ZoneId.of(iParams[1].toString())); + if (params.length > 0) { + if (params.length > 1) + result = now.atZone(ZoneId.of(params[1].toString())); } - return DateUtils.getDate(result, iContext.getDatabase().getSerializer().getDateTimeImplementation()); + return DateUtils.getDate(result, context.getDatabase().getSerializer().getDateTimeImplementation()); } public String getSyntax() { diff --git a/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodField.java b/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodField.java index d0b2f2624b..7d2e21b194 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodField.java +++ b/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodField.java @@ -42,8 +42,8 @@ public Object execute(final Object value, final Identifiable iCurrentRecord, fin final String field = iParams[0].toString(); - if (value instanceof Identifiable) { - final Document doc = (Document) ((Identifiable) value).getRecord(); + if (value instanceof Identifiable identifiable) { + final Document doc = (Document) identifiable.getRecord(); return doc.get(field); } diff --git a/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodJoin.java b/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodJoin.java index 89f748536b..09a9450490 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodJoin.java +++ b/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodJoin.java @@ -47,7 +47,7 @@ public Object execute(final Object value, return null; } - if (value instanceof List) { + if (value instanceof List list) { final String separator = Optional.ofNullable(params) .filter(p -> p.length > 0) @@ -55,7 +55,7 @@ public Object execute(final Object value, .map(p -> p[0].toString()) .orElse(","); - return ((List) value).stream() + return list.stream() .map(Object::toString) .collect(Collectors.joining(separator)); diff --git a/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodKeys.java b/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodKeys.java index 76feed4c76..c631293c23 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodKeys.java +++ b/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodKeys.java @@ -40,22 +40,19 @@ public SQLMethodKeys() { @Override public Object execute(final Object value, final Identifiable iCurrentRecord, final CommandContext iContext, final Object[] iParams) { - if (value instanceof Map) - return ((Map) value).keySet(); + if (value instanceof Map map) return map.keySet(); - if (value instanceof Document) - return Collections.singletonList(((Document) value).getPropertyNames()); + if (value instanceof Document document) return Collections.singletonList(document.getPropertyNames()); - if (value instanceof Result) { - final Result res = (Result) value; - return res.getPropertyNames(); + if (value instanceof Result result) { + return result.getPropertyNames(); } - if (value instanceof Collection) { - final List result = new ArrayList<>(); - for (final Object o : (Collection) value) { - result.addAll((Collection) execute(value, iCurrentRecord, iContext, iParams)); - } + if (value instanceof Collection collection) { + final List result = collection.stream() + .flatMap(o -> ((Collection) execute(o, iCurrentRecord, iContext, iParams)) + .stream()) + .toList(); return result; } return null; diff --git a/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodRemove.java b/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodRemove.java index 263ed6b166..73f92069aa 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodRemove.java +++ b/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodRemove.java @@ -41,8 +41,8 @@ public SQLMethodRemove() { public Object execute(Object value, final Identifiable currentRecord, final CommandContext context, final Object[] params) { if (params != null && params.length > 0 && params[0] != null) { final Object[] arguments = MultiValue.array(params, Object.class, argument -> { - if (argument instanceof String && ((String) argument).startsWith("$")) { - return context.getVariable((String) argument); + if (argument instanceof String string && string.startsWith("$")) { + return context.getVariable(string); } return argument; }); diff --git a/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodRemoveAll.java b/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodRemoveAll.java index f8c04f5241..579f1664dd 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodRemoveAll.java +++ b/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodRemoveAll.java @@ -41,9 +41,9 @@ public SQLMethodRemoveAll() { public Object execute(Object value, final Identifiable currentRecord, final CommandContext context, final Object[] params) { if (params != null && params.length > 0 && params[0] != null) { final Object[] arguments = MultiValue.array(params, Object.class, iArgument -> { - if (iArgument instanceof String && - ((String) iArgument).startsWith("$")) { - return context.getVariable((String) iArgument); + if (iArgument instanceof String string && + string.startsWith("$")) { + return context.getVariable(string); } return iArgument; }); diff --git a/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodSort.java b/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodSort.java index 9d5e00e3d8..a5b1bb32d3 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodSort.java +++ b/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodSort.java @@ -41,9 +41,12 @@ public SQLMethodSort() { public Object execute(final Object value, final Identifiable iCurrentRecord, final CommandContext iContext, final Object[] iParams) { - if (value != null && value instanceof List) { - List result = new ArrayList((List) value); - if (iParams != null && iParams.length > 0 && iParams[0] != null && iParams[0] instanceof Boolean && !((Boolean) iParams[0])) + if (value != null && value instanceof List list) { + List result = new ArrayList(list); + if (iParams != null && + iParams.length > 0 && + iParams[0] != null && + iParams[0] instanceof Boolean bool && !bool) result.sort((left, right) -> BinaryComparator.compareTo(right, left)); else result.sort((left, right) -> BinaryComparator.compareTo(left, right)); diff --git a/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodTransform.java b/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodTransform.java index 2d5c92a292..3053b91c81 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodTransform.java +++ b/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodTransform.java @@ -62,9 +62,9 @@ public Object execute(final Object value, final Identifiable iCurrentRecord, fin transformers.add(methodFactory.createMethod(o.toString())); } - if (value instanceof List) { - final List newList = new ArrayList<>(((List) value).size()); - for (Object o : (List) value) { + if (value instanceof List list) { + final List newList = new ArrayList<>(list.size()); + for (Object o : list) { Object transformed = o; for (SQLMethod m : transformers) @@ -73,9 +73,9 @@ public Object execute(final Object value, final Identifiable iCurrentRecord, fin newList.add(transformed); } return newList; - } else if (value instanceof Set) { - final Set newSet = new HashSet<>(((Set) value).size()); - for (Object o : (Set) value) { + } else if (value instanceof Set set) { + final Set newSet = new HashSet<>(set.size()); + for (Object o : set) { Object transformed = o; for (SQLMethod m : transformers) diff --git a/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodValues.java b/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodValues.java index d14818a2ae..7a2a0838f8 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodValues.java +++ b/engine/src/main/java/com/arcadedb/query/sql/method/collection/SQLMethodValues.java @@ -40,15 +40,13 @@ public SQLMethodValues() { } @Override - public Object execute(final Object value, final Identifiable iCurrentRecord, final CommandContext iContext, final Object[] iParams) { - if (value instanceof Map) - return ((Map) value).values(); - else if (value instanceof Document) - return List.of(((Document) value).toMap().values()); - else if (value instanceof Result) { - final Result res = (Result) value; - return res.toMap().values(); - } + public Object execute(final Object value, final Identifiable iCurrentRecord, final CommandContext iContext, + final Object[] iParams) { + + if (value instanceof Map map) return map.values(); + else if (value instanceof Document document) return List.of(document.toMap().values()); + else if (value instanceof Result result) return result.toMap().values(); + return null; } } diff --git a/engine/src/main/java/com/arcadedb/query/sql/method/conversion/SQLMethodAsBoolean.java b/engine/src/main/java/com/arcadedb/query/sql/method/conversion/SQLMethodAsBoolean.java index b5bf2fcc07..9724036f5a 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/method/conversion/SQLMethodAsBoolean.java +++ b/engine/src/main/java/com/arcadedb/query/sql/method/conversion/SQLMethodAsBoolean.java @@ -35,16 +35,11 @@ public SQLMethodAsBoolean() { } @Override - public Object execute(final Object value, final Identifiable currentRecord, final CommandContext context, - final Object[] params) { - if (value == null) - return null; - if (value instanceof Boolean) - return value; - if (value instanceof String) - return Boolean.valueOf(((String) value).trim()); - else if (value instanceof Number) - return ((Number) value).intValue() != 0; + public Object execute(final Object value, final Identifiable currentRecord, final CommandContext context, final Object[] params) { + if (value == null) return null; + if (value instanceof Boolean) return value; + if (value instanceof String string) return Boolean.valueOf(string.trim()); + else if (value instanceof Number number) return number.intValue() != 0; return Boolean.FALSE; } } diff --git a/engine/src/main/java/com/arcadedb/query/sql/method/conversion/SQLMethodAsByte.java b/engine/src/main/java/com/arcadedb/query/sql/method/conversion/SQLMethodAsByte.java index 564934efbd..2f6267fe91 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/method/conversion/SQLMethodAsByte.java +++ b/engine/src/main/java/com/arcadedb/query/sql/method/conversion/SQLMethodAsByte.java @@ -38,8 +38,7 @@ public SQLMethodAsByte() { @Override public Object execute(final Object value, final Identifiable iCurrentRecord, final CommandContext iContext, final Object[] iParams) { - if (value instanceof Number) - return ((Number) value).byteValue(); + if (value instanceof Number number) return number.byteValue(); return value != null ? Byte.valueOf(value.toString().trim()) : null; } } diff --git a/engine/src/main/java/com/arcadedb/query/sql/method/conversion/SQLMethodAsDate.java b/engine/src/main/java/com/arcadedb/query/sql/method/conversion/SQLMethodAsDate.java index 22527c2329..7c7acfa52f 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/method/conversion/SQLMethodAsDate.java +++ b/engine/src/main/java/com/arcadedb/query/sql/method/conversion/SQLMethodAsDate.java @@ -47,16 +47,17 @@ public String getSyntax() { } @Override - public Object execute(final Object value, final Identifiable iCurrentRecord, final CommandContext context, final Object[] iParams) { - if (value == null) - return null; - - if (value instanceof Date) - return value; - else if (value instanceof Number) - return new Date(((Number) value).longValue()); - - final String format = iParams.length > 0 ? iParams[0].toString() : context.getDatabase().getSchema().getDateFormat(); - return DateUtils.getDate(DateUtils.parse(value.toString(), format), context.getDatabase().getSerializer().getDateImplementation()); + public Object execute(final Object value, + final Identifiable currentRecord, + final CommandContext context, + final Object[] params) { + if (value == null) return null; + + if (value instanceof Date) return value; + else if (value instanceof Number number) return new Date(number.longValue()); + + final String format = params.length > 0 ? params[0].toString() : context.getDatabase().getSchema().getDateFormat(); + return DateUtils.getDate(DateUtils.parse(value.toString(), format), + context.getDatabase().getSerializer().getDateImplementation()); } } diff --git a/engine/src/main/java/com/arcadedb/query/sql/method/conversion/SQLMethodAsDateTime.java b/engine/src/main/java/com/arcadedb/query/sql/method/conversion/SQLMethodAsDateTime.java index 0b0c001ad3..54cac8a111 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/method/conversion/SQLMethodAsDateTime.java +++ b/engine/src/main/java/com/arcadedb/query/sql/method/conversion/SQLMethodAsDateTime.java @@ -53,8 +53,8 @@ public Object execute(final Object value, final Identifiable iCurrentRecord, fin if (value instanceof Date) return value; - else if (value instanceof Number) - return new Date(((Number) value).longValue()); + else if (value instanceof Number number) + return new Date(number.longValue()); final String format = iParams.length > 0 ? iParams[0].toString() : context.getDatabase().getSchema().getDateTimeFormat(); final Object date = DateUtils.parse(value.toString(), format); diff --git a/engine/src/main/java/com/arcadedb/query/sql/method/misc/SQLMethodPrecision.java b/engine/src/main/java/com/arcadedb/query/sql/method/misc/SQLMethodPrecision.java index 8af8c6b330..04bda18504 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/method/misc/SQLMethodPrecision.java +++ b/engine/src/main/java/com/arcadedb/query/sql/method/misc/SQLMethodPrecision.java @@ -28,6 +28,8 @@ import java.time.temporal.*; import java.util.*; +import static java.time.temporal.ChronoUnit.MILLIS; + /** * Modifies the precision of a datetime. * @@ -42,26 +44,22 @@ public SQLMethodPrecision() { } @Override - public Object execute(final Object value, final Identifiable iCurrentRecord, final CommandContext iContext, final Object[] iParams) { + public Object execute(final Object value, final Identifiable iCurrentRecord, final CommandContext iContext, + final Object[] iParams) { if (iParams == null || iParams.length == 0 || iParams[0] == null) throw new IllegalArgumentException("precision method was expecting the time unit"); final ChronoUnit targetPrecision = DateUtils.parsePrecision(iParams[0].toString()); - if (value instanceof LocalDateTime) - return ((LocalDateTime) value).truncatedTo(targetPrecision); - else if (value instanceof ZonedDateTime) - return ((ZonedDateTime) value).truncatedTo(targetPrecision); - else if (value instanceof Instant) - return ((Instant) value).truncatedTo(targetPrecision); - else if (value instanceof Date) { - if (targetPrecision == ChronoUnit.MILLIS) - return value; - return DateUtils.dateTime(iContext.getDatabase(), ((Date) value).getTime(), ChronoUnit.MILLIS, LocalDateTime.class, targetPrecision); - } else if (value instanceof Calendar) { - if (targetPrecision == ChronoUnit.MILLIS) - return value; - return DateUtils.dateTime(iContext.getDatabase(), ((Calendar) value).getTimeInMillis(), ChronoUnit.MILLIS, LocalDateTime.class, targetPrecision); + if (value instanceof LocalDateTime localDateTime) return localDateTime.truncatedTo(targetPrecision); + else if (value instanceof ZonedDateTime zonedDateTime) return zonedDateTime.truncatedTo(targetPrecision); + else if (value instanceof Instant instant) return instant.truncatedTo(targetPrecision); + else if (value instanceof Date date) { + if (targetPrecision == MILLIS) return value; + return DateUtils.dateTime(iContext.getDatabase(), date.getTime(), MILLIS, LocalDateTime.class, targetPrecision); + } else if (value instanceof Calendar calendar) { + if (targetPrecision == MILLIS) return calendar; + return DateUtils.dateTime(iContext.getDatabase(), calendar.getTimeInMillis(), MILLIS, LocalDateTime.class, targetPrecision); } throw new CommandExecutionException("Error on changing precision for unsupported type '" + value.getClass() + "'"); diff --git a/engine/src/main/java/com/arcadedb/query/sql/method/string/SQLMethodFormat.java b/engine/src/main/java/com/arcadedb/query/sql/method/string/SQLMethodFormat.java index 9e26b631e3..a20e9b2fea 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/method/string/SQLMethodFormat.java +++ b/engine/src/main/java/com/arcadedb/query/sql/method/string/SQLMethodFormat.java @@ -52,7 +52,7 @@ public Object execute(final Object value, final Identifiable iRecord, final Comm if (isCollectionOfDates(value)) { final List result = new ArrayList(); - final Iterator iterator = MultiValue.getMultiValueIterator(value); + final Iterator iterator = MultiValue.getMultiValueIterator(value); while (iterator.hasNext()) result.add(DateUtils.format(iterator.next(), format)); @@ -67,7 +67,7 @@ public Object execute(final Object value, final Identifiable iRecord, final Comm private boolean isCollectionOfDates(final Object value) { if (MultiValue.isMultiValue(value)) { - final Iterator iterator = MultiValue.getMultiValueIterator(value); + final Iterator iterator = MultiValue.getMultiValueIterator(value); while (iterator.hasNext()) { final Object item = iterator.next(); if (item != null && !DateUtils.isDate(item)) { diff --git a/engine/src/main/java/com/arcadedb/query/sql/parser/AndBlock.java b/engine/src/main/java/com/arcadedb/query/sql/parser/AndBlock.java index 991faeb236..38c4542b5e 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/parser/AndBlock.java +++ b/engine/src/main/java/com/arcadedb/query/sql/parser/AndBlock.java @@ -39,19 +39,16 @@ public AndBlock(final List... expressions) { super(-1); int total = 0; - for (int i = 0; i < expressions.length; i++) - total += expressions[i].size(); + for (List expression : expressions) total += expression.size(); this.subBlocks = new ArrayList<>(total); - for (int i = 0; i < expressions.length; i++) - subBlocks.addAll(expressions[i]); + for (List expression : expressions) subBlocks.addAll(expression); } @Override public Boolean evaluate(final Identifiable currentRecord, final CommandContext context) { - if (getSubBlocks() == null) - return true; + if (getSubBlocks() == null) return true; for (final BooleanExpression block : subBlocks) { if (!block.evaluate(currentRecord, context)) { @@ -63,15 +60,12 @@ public Boolean evaluate(final Identifiable currentRecord, final CommandContext c @Override public Boolean evaluate(final Result currentRecord, final CommandContext context) { - if (getSubBlocks() == null) - return true; + if (getSubBlocks() == null) return true; for (final BooleanExpression block : subBlocks) { final Boolean result = block.evaluate(currentRecord, context); - if (result == null) - return null; - else if (!result) - return false; + if (result == null) return null; + else if (!result) return false; } return true; } @@ -81,13 +75,11 @@ public List getSubBlocks() { } public void toString(final Map params, final StringBuilder builder) { - if (subBlocks == null || subBlocks.size() == 0) - return; + if (subBlocks == null || subBlocks.isEmpty()) return; boolean first = true; for (BooleanExpression expr : subBlocks) { - if (!first) - builder.append(" AND "); + if (!first) builder.append(" AND "); expr.toString(params, builder); first = false; @@ -101,11 +93,11 @@ public List getIndexedFunctionConditions(final DocumentType iSc final List result = new ArrayList<>(); for (final BooleanExpression exp : subBlocks) { final List sub = exp.getIndexedFunctionConditions(iSchemaClass, context); - if (sub != null && sub.size() > 0) { + if (sub != null && !sub.isEmpty()) { result.addAll(sub); } } - return result.size() == 0 ? null : result; + return result.isEmpty() ? null : result; } public List flatten() { @@ -195,8 +187,7 @@ protected SimpleNode[] getCacheableElements() { @Override public boolean isAlwaysTrue() { - if (subBlocks.isEmpty()) - return true; + if (subBlocks.isEmpty()) return true; for (BooleanExpression exp : subBlocks) { if (!exp.isAlwaysTrue()) { diff --git a/engine/src/main/java/com/arcadedb/query/sql/parser/ArrayConcatExpression.java b/engine/src/main/java/com/arcadedb/query/sql/parser/ArrayConcatExpression.java index 750f2c7f2b..2813e7eaa2 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/parser/ArrayConcatExpression.java +++ b/engine/src/main/java/com/arcadedb/query/sql/parser/ArrayConcatExpression.java @@ -69,7 +69,7 @@ public Object apply(final Object left, final Object right) { final List result = new ArrayList<>(); if (MultiValue.isMultiValue(left)) { - final Iterator leftIter = MultiValue.getMultiValueIterator(left); + final Iterator leftIter = MultiValue.getMultiValueIterator(left); while (leftIter.hasNext()) { result.add(leftIter.next()); } @@ -78,7 +78,7 @@ public Object apply(final Object left, final Object right) { } if (MultiValue.isMultiValue(right)) { - final Iterator rightIter = MultiValue.getMultiValueIterator(right); + final Iterator rightIter = MultiValue.getMultiValueIterator(right); while (rightIter.hasNext()) { result.add(rightIter.next()); } diff --git a/engine/src/main/java/com/arcadedb/query/sql/parser/ArraySingleValuesSelector.java b/engine/src/main/java/com/arcadedb/query/sql/parser/ArraySingleValuesSelector.java index 0d55ede34d..a8619b3efa 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/parser/ArraySingleValuesSelector.java +++ b/engine/src/main/java/com/arcadedb/query/sql/parser/ArraySingleValuesSelector.java @@ -65,7 +65,7 @@ public Object execute(final Identifiable iCurrentRecord, final Object iResult, f } else if (iResult instanceof Result && index instanceof String) { result.add(((Result) iResult).getProperty((String) index)); } else if (MultiValue.isMultiValue(iResult)) { - final Iterator iter = MultiValue.getMultiValueIterator(iResult); + final Iterator iter = MultiValue.getMultiValueIterator(iResult); while (iter.hasNext()) { result.add(calculateValue(iter.next(), index)); } @@ -97,7 +97,7 @@ public Object execute(final Result iCurrentRecord, final Object iResult, final C } else if (iResult instanceof Result && index instanceof String) { result.add(((Result) iResult).getProperty((String) index)); } else if (MultiValue.isMultiValue(iResult)) { - final Iterator iter = MultiValue.getMultiValueIterator(iResult); + final Iterator iter = MultiValue.getMultiValueIterator(iResult); while (iter.hasNext()) { result.add(calculateValue(iter.next(), index)); } @@ -121,7 +121,7 @@ private Object calculateValue(final Object item, final Object index) { } else if (item instanceof Result && index instanceof String) { return ((Result) item).getProperty((String) index); } else if (MultiValue.isMultiValue(item)) { - final Iterator iter = MultiValue.getMultiValueIterator(item); + final Iterator iter = MultiValue.getMultiValueIterator(item); final List result = new ArrayList<>(); while (iter.hasNext()) { result.add(calculateValue(iter.next(), index)); diff --git a/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsAllCondition.java b/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsAllCondition.java index 81f15a2a3b..adb86e34e9 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsAllCondition.java +++ b/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsAllCondition.java @@ -93,7 +93,7 @@ public Boolean evaluate(final Identifiable currentRecord, final CommandContext c if (!MultiValue.isMultiValue(leftValue)) return false; - final Iterator iter = MultiValue.getMultiValueIterator(leftValue); + final Iterator iter = MultiValue.getMultiValueIterator(leftValue); while (iter.hasNext()) { final Object item = iter.next(); if (item instanceof Identifiable) { @@ -122,7 +122,7 @@ public Boolean evaluate(final Result currentRecord, final CommandContext context if (!MultiValue.isMultiValue(leftValue)) return false; - final Iterator iter = MultiValue.getMultiValueIterator(leftValue); + final Iterator iter = MultiValue.getMultiValueIterator(leftValue); while (iter.hasNext()) { final Object item = iter.next(); if (item instanceof Identifiable) { diff --git a/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsAnyCondition.java b/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsAnyCondition.java index 3bd5ef6967..ef5e5ec1f3 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsAnyCondition.java +++ b/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsAnyCondition.java @@ -85,7 +85,7 @@ public Boolean evaluate(final Identifiable currentRecord, final CommandContext c if (!MultiValue.isMultiValue(leftValue)) return false; - final Iterator iter = MultiValue.getMultiValueIterator(leftValue); + final Iterator iter = MultiValue.getMultiValueIterator(leftValue); while (iter.hasNext()) { final Object item = iter.next(); if (item instanceof Identifiable) { @@ -111,7 +111,7 @@ public Boolean evaluate(final Result currentRecord, final CommandContext context if (!MultiValue.isMultiValue(leftValue)) return false; - final Iterator iter = MultiValue.getMultiValueIterator(leftValue); + final Iterator iter = MultiValue.getMultiValueIterator(leftValue); while (iter.hasNext()) { final Object item = iter.next(); if (item instanceof Identifiable) { diff --git a/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsCondition.java b/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsCondition.java index 5ff8724289..dd64e389db 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsCondition.java +++ b/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsCondition.java @@ -136,7 +136,7 @@ public Boolean evaluate(final Identifiable currentRecord, final CommandContext c if (!MultiValue.isMultiValue(leftValue)) return false; - final Iterator iter = MultiValue.getMultiValueIterator(leftValue); + final Iterator iter = MultiValue.getMultiValueIterator(leftValue); while (iter.hasNext()) { final Object item = iter.next(); if (item instanceof Identifiable && condition.evaluate((Identifiable) item, context)) @@ -160,7 +160,7 @@ public Boolean evaluate(final Result currentRecord, final CommandContext context if (!MultiValue.isMultiValue(leftValue)) return false; - final Iterator iter = MultiValue.getMultiValueIterator(leftValue); + final Iterator iter = MultiValue.getMultiValueIterator(leftValue); while (iter.hasNext()) { final Object item = iter.next(); if (item instanceof Identifiable && condition.evaluate((Identifiable) item, context)) diff --git a/engine/src/main/java/com/arcadedb/utility/DateUtils.java b/engine/src/main/java/com/arcadedb/utility/DateUtils.java index 2ba77632c0..713a8ecaa3 100755 --- a/engine/src/main/java/com/arcadedb/utility/DateUtils.java +++ b/engine/src/main/java/com/arcadedb/utility/DateUtils.java @@ -41,14 +41,12 @@ public static Object dateTime(final Database database, final long timestamp, fin final Object value; if (dateTimeImplementation.equals(Date.class)) { - if (destinationPrecision == ChronoUnit.MICROS || destinationPrecision == ChronoUnit.NANOS) - throw new IllegalArgumentException( - "java.util.Date implementation cannot handle datetime with precision " + destinationPrecision); + if (destinationPrecision == ChronoUnit.MICROS || destinationPrecision == ChronoUnit.NANOS) throw new IllegalArgumentException( + "java.util.Date implementation cannot handle datetime with precision " + destinationPrecision); value = new Date(convertedTimestamp); } else if (dateTimeImplementation.equals(Calendar.class)) { - if (destinationPrecision == ChronoUnit.MICROS || destinationPrecision == ChronoUnit.NANOS) - throw new IllegalArgumentException( - "java.util.Calendar implementation cannot handle datetime with precision " + destinationPrecision); + if (destinationPrecision == ChronoUnit.MICROS || destinationPrecision == ChronoUnit.NANOS) throw new IllegalArgumentException( + "java.util.Calendar implementation cannot handle datetime with precision " + destinationPrecision); value = Calendar.getInstance(database.getSchema().getTimeZone()); ((Calendar) value).setTimeInMillis(convertedTimestamp); } else if (dateTimeImplementation.equals(LocalDateTime.class)) { @@ -56,47 +54,39 @@ public static Object dateTime(final Database database, final long timestamp, fin value = LocalDateTime.ofInstant(Instant.ofEpochSecond(convertedTimestamp), UTC_ZONE_ID); else if (destinationPrecision.equals(ChronoUnit.MILLIS)) value = LocalDateTime.ofInstant(Instant.ofEpochMilli(convertedTimestamp), UTC_ZONE_ID); - else if (destinationPrecision.equals(ChronoUnit.MICROS)) - value = LocalDateTime.ofInstant(Instant.ofEpochSecond(TimeUnit.MICROSECONDS.toSeconds(convertedTimestamp), - TimeUnit.MICROSECONDS.toNanos(Math.floorMod(convertedTimestamp, TimeUnit.SECONDS.toMicros(1)))), UTC_ZONE_ID); + else if (destinationPrecision.equals(ChronoUnit.MICROS)) value = LocalDateTime.ofInstant( + Instant.ofEpochSecond(TimeUnit.MICROSECONDS.toSeconds(convertedTimestamp), + TimeUnit.MICROSECONDS.toNanos(Math.floorMod(convertedTimestamp, TimeUnit.SECONDS.toMicros(1)))), UTC_ZONE_ID); else if (destinationPrecision.equals(ChronoUnit.NANOS)) value = LocalDateTime.ofInstant(Instant.ofEpochSecond(0L, convertedTimestamp), UTC_ZONE_ID); - else - value = 0; + else value = 0; } else if (dateTimeImplementation.equals(ZonedDateTime.class)) { if (destinationPrecision.equals(ChronoUnit.SECONDS)) value = ZonedDateTime.ofInstant(Instant.ofEpochSecond(convertedTimestamp), UTC_ZONE_ID); else if (destinationPrecision.equals(ChronoUnit.MILLIS)) value = ZonedDateTime.ofInstant(Instant.ofEpochMilli(convertedTimestamp), UTC_ZONE_ID); - else if (destinationPrecision.equals(ChronoUnit.MICROS)) - value = ZonedDateTime.ofInstant(Instant.ofEpochSecond(TimeUnit.MICROSECONDS.toSeconds(convertedTimestamp), - TimeUnit.MICROSECONDS.toNanos(Math.floorMod(convertedTimestamp, TimeUnit.SECONDS.toMicros(1)))), UTC_ZONE_ID); + else if (destinationPrecision.equals(ChronoUnit.MICROS)) value = ZonedDateTime.ofInstant( + Instant.ofEpochSecond(TimeUnit.MICROSECONDS.toSeconds(convertedTimestamp), + TimeUnit.MICROSECONDS.toNanos(Math.floorMod(convertedTimestamp, TimeUnit.SECONDS.toMicros(1)))), UTC_ZONE_ID); else if (destinationPrecision.equals(ChronoUnit.NANOS)) value = ZonedDateTime.ofInstant(Instant.ofEpochSecond(0L, convertedTimestamp), UTC_ZONE_ID); - else - value = 0; + else value = 0; } else if (dateTimeImplementation.equals(Instant.class)) { - if (destinationPrecision.equals(ChronoUnit.SECONDS)) - value = Instant.ofEpochSecond(convertedTimestamp); - else if (destinationPrecision.equals(ChronoUnit.MILLIS)) - value = Instant.ofEpochMilli(convertedTimestamp); + if (destinationPrecision.equals(ChronoUnit.SECONDS)) value = Instant.ofEpochSecond(convertedTimestamp); + else if (destinationPrecision.equals(ChronoUnit.MILLIS)) value = Instant.ofEpochMilli(convertedTimestamp); else if (destinationPrecision.equals(ChronoUnit.MICROS)) value = Instant.ofEpochSecond(TimeUnit.MICROSECONDS.toSeconds(convertedTimestamp), TimeUnit.MICROSECONDS.toNanos(Math.floorMod(convertedTimestamp, TimeUnit.SECONDS.toMicros(1)))); - else if (destinationPrecision.equals(ChronoUnit.NANOS)) - value = Instant.ofEpochSecond(0L, convertedTimestamp); - else - value = 0; - } else - throw new SerializationException( - "Error on deserialize datetime. Configured class '" + dateTimeImplementation + "' is not supported"); + else if (destinationPrecision.equals(ChronoUnit.NANOS)) value = Instant.ofEpochSecond(0L, convertedTimestamp); + else value = 0; + } else throw new SerializationException( + "Error on deserialize datetime. Configured class '" + dateTimeImplementation + "' is not supported"); return value; } public static Object date(final Database database, final long timestamp, final Class dateImplementation) { final Object value; - if (dateImplementation.equals(Date.class)) - value = new Date(timestamp * MS_IN_A_DAY); + if (dateImplementation.equals(Date.class)) value = new Date(timestamp * MS_IN_A_DAY); else if (dateImplementation.equals(Calendar.class)) { value = Calendar.getInstance(database.getSchema().getTimeZone()); ((Calendar) value).setTimeInMillis(timestamp * MS_IN_A_DAY); @@ -119,19 +109,15 @@ public static Long dateTimeToTimestamp(final Object value, final ChronoUnit prec timestamp = convertTimestamp(((Calendar) value).getTimeInMillis(), ChronoUnit.MILLIS, precisionToUse); else if (value instanceof LocalDateTime) { final LocalDateTime localDateTime = (LocalDateTime) value; - if (precisionToUse.equals(ChronoUnit.SECONDS)) - timestamp = localDateTime.toInstant(ZoneOffset.UTC).getEpochSecond(); - else if (precisionToUse.equals(ChronoUnit.MILLIS)) - timestamp = - TimeUnit.MILLISECONDS.convert(localDateTime.toEpochSecond(ZoneOffset.UTC), TimeUnit.SECONDS) + localDateTime.getLong( - ChronoField.MILLI_OF_SECOND); - else if (precisionToUse.equals(ChronoUnit.MICROS)) - timestamp = - TimeUnit.MICROSECONDS.convert(localDateTime.toEpochSecond(ZoneOffset.UTC), TimeUnit.SECONDS) + (localDateTime.getNano() - / 1000); - else if (precisionToUse.equals(ChronoUnit.NANOS)) - timestamp = - TimeUnit.NANOSECONDS.convert(localDateTime.toEpochSecond(ZoneOffset.UTC), TimeUnit.SECONDS) + localDateTime.getNano(); + if (precisionToUse.equals(ChronoUnit.SECONDS)) timestamp = localDateTime.toInstant(ZoneOffset.UTC).getEpochSecond(); + else if (precisionToUse.equals(ChronoUnit.MILLIS)) timestamp = + TimeUnit.MILLISECONDS.convert(localDateTime.toEpochSecond(ZoneOffset.UTC), TimeUnit.SECONDS) + localDateTime.getLong( + ChronoField.MILLI_OF_SECOND); + else if (precisionToUse.equals(ChronoUnit.MICROS)) timestamp = + TimeUnit.MICROSECONDS.convert(localDateTime.toEpochSecond(ZoneOffset.UTC), TimeUnit.SECONDS) + (localDateTime.getNano() + / 1000); + else if (precisionToUse.equals(ChronoUnit.NANOS)) timestamp = + TimeUnit.NANOSECONDS.convert(localDateTime.toEpochSecond(ZoneOffset.UTC), TimeUnit.SECONDS) + localDateTime.getNano(); else // NOT SUPPORTED timestamp = 0; @@ -150,13 +136,10 @@ else if (precisionToUse.equals(ChronoUnit.NANOS)) timestamp = 0; } else if (value instanceof ZonedDateTime) { final ZonedDateTime zonedDateTime = (ZonedDateTime) value; - if (precisionToUse.equals(ChronoUnit.SECONDS)) - timestamp = zonedDateTime.toInstant().getEpochSecond(); - else if (precisionToUse.equals(ChronoUnit.MILLIS)) - timestamp = zonedDateTime.toInstant().toEpochMilli(); - else if (precisionToUse.equals(ChronoUnit.MICROS)) - timestamp = - TimeUnit.MICROSECONDS.convert(zonedDateTime.toEpochSecond(), TimeUnit.SECONDS) + (zonedDateTime.getNano() / 1000); + if (precisionToUse.equals(ChronoUnit.SECONDS)) timestamp = zonedDateTime.toInstant().getEpochSecond(); + else if (precisionToUse.equals(ChronoUnit.MILLIS)) timestamp = zonedDateTime.toInstant().toEpochMilli(); + else if (precisionToUse.equals(ChronoUnit.MICROS)) timestamp = + TimeUnit.MICROSECONDS.convert(zonedDateTime.toEpochSecond(), TimeUnit.SECONDS) + (zonedDateTime.getNano() / 1000); else if (precisionToUse.equals(ChronoUnit.NANOS)) timestamp = TimeUnit.NANOSECONDS.convert(zonedDateTime.toEpochSecond(), TimeUnit.SECONDS) + zonedDateTime.getNano(); else @@ -164,10 +147,8 @@ else if (precisionToUse.equals(ChronoUnit.NANOS)) timestamp = 0; } else if (value instanceof Instant) { final Instant instant = (Instant) value; - if (precisionToUse.equals(ChronoUnit.SECONDS)) - timestamp = instant.getEpochSecond(); - else if (precisionToUse.equals(ChronoUnit.MILLIS)) - timestamp = instant.toEpochMilli(); + if (precisionToUse.equals(ChronoUnit.SECONDS)) timestamp = instant.getEpochSecond(); + else if (precisionToUse.equals(ChronoUnit.MILLIS)) timestamp = instant.toEpochMilli(); else if (precisionToUse.equals(ChronoUnit.MICROS)) timestamp = TimeUnit.MICROSECONDS.convert(instant.getEpochSecond(), TimeUnit.SECONDS) + (instant.getNano() / 1000); else if (precisionToUse.equals(ChronoUnit.NANOS)) @@ -175,13 +156,10 @@ else if (precisionToUse.equals(ChronoUnit.NANOS)) else // NOT SUPPORTED timestamp = 0; - } else if (value instanceof Number) - timestamp = ((Number) value).longValue(); + } else if (value instanceof Number) timestamp = ((Number) value).longValue(); else if (value instanceof String) { - if (FileUtils.isLong((String) value)) - timestamp = Long.parseLong(value.toString()); - else - return dateTimeToTimestamp(LocalDateTime.parse((String) value), precisionToUse); + if (FileUtils.isLong((String) value)) timestamp = Long.parseLong(value.toString()); + else return dateTimeToTimestamp(LocalDateTime.parse((String) value), precisionToUse); } else // UNSUPPORTED return null; @@ -190,91 +168,59 @@ else if (value instanceof String) { } public static ChronoUnit parsePrecision(final String precision) { - switch (precision) { - case "year": - return ChronoUnit.YEARS; - case "month": - return ChronoUnit.MONTHS; - case "week": - return ChronoUnit.WEEKS; - case "day": - return ChronoUnit.DAYS; - case "hour": - return ChronoUnit.HOURS; - case "minute": - return ChronoUnit.MINUTES; - case "second": - return ChronoUnit.SECONDS; - case "millisecond": - return ChronoUnit.MILLIS; - case "microsecond": - return ChronoUnit.MICROS; - case "nanosecond": - return ChronoUnit.NANOS; - default: - throw new SerializationException("Unsupported datetime precision '" + precision + "'"); - } + return switch (precision.toLowerCase(Locale.ENGLISH)) { + case "year", "years" -> ChronoUnit.YEARS; + case "month", "months" -> ChronoUnit.MONTHS; + case "week", "weeks" -> ChronoUnit.WEEKS; + case "day", "days" -> ChronoUnit.DAYS; + case "hour", "hours" -> ChronoUnit.HOURS; + case "minute", "minutes" -> ChronoUnit.MINUTES; + case "second", "seconds" -> ChronoUnit.SECONDS; + case "millisecond", "milliseconds", "millis" -> ChronoUnit.MILLIS; + case "microsecond", "microseconds", "micros" -> ChronoUnit.MICROS; + case "nanosecond", "nanoseconds", "nanos" -> ChronoUnit.NANOS; + default -> throw new SerializationException("Unsupported datetime precision '" + precision + "'"); + }; } public static ChronoUnit getPrecision(final int nanos) { - if (nanos % 1_000_000_000 == 0) - return ChronoUnit.SECONDS; - if (nanos % 1_000_000 == 0) - return ChronoUnit.MILLIS; - if (nanos % 1_000 == 0) - return ChronoUnit.MICROS; - else - return ChronoUnit.NANOS; + if (nanos % 1_000_000_000 == 0) return ChronoUnit.SECONDS; + if (nanos % 1_000_000 == 0) return ChronoUnit.MILLIS; + if (nanos % 1_000 == 0) return ChronoUnit.MICROS; + else return ChronoUnit.NANOS; } public static long convertTimestamp(final long timestamp, final ChronoUnit from, final ChronoUnit to) { - if (from == to) - return timestamp; + if (from == to) return timestamp; if (from == ChronoUnit.SECONDS) { - if (to == ChronoUnit.MILLIS) - return timestamp * 1_000; - else if (to == ChronoUnit.MICROS) - return timestamp * 1_000_000; - else if (to == ChronoUnit.NANOS) - return timestamp * 1_000_000_000; + if (to == ChronoUnit.MILLIS) return timestamp * 1_000; + else if (to == ChronoUnit.MICROS) return timestamp * 1_000_000; + else if (to == ChronoUnit.NANOS) return timestamp * 1_000_000_000; } else if (from == ChronoUnit.MILLIS) { - if (to == ChronoUnit.SECONDS) - return timestamp / 1_000; - else if (to == ChronoUnit.MICROS) - return timestamp * 1_000; - else if (to == ChronoUnit.NANOS) - return timestamp * 1_000_000; + if (to == ChronoUnit.SECONDS) return timestamp / 1_000; + else if (to == ChronoUnit.MICROS) return timestamp * 1_000; + else if (to == ChronoUnit.NANOS) return timestamp * 1_000_000; } else if (from == ChronoUnit.MICROS) { - if (to == ChronoUnit.SECONDS) - return timestamp / 1_000_000; - else if (to == ChronoUnit.MILLIS) - return timestamp / 1_000; - else if (to == ChronoUnit.NANOS) - return timestamp * 1_000; + if (to == ChronoUnit.SECONDS) return timestamp / 1_000_000; + else if (to == ChronoUnit.MILLIS) return timestamp / 1_000; + else if (to == ChronoUnit.NANOS) return timestamp * 1_000; } else if (from == ChronoUnit.NANOS) { - if (to == ChronoUnit.SECONDS) - return timestamp / 1_000_000_000; - else if (to == ChronoUnit.MILLIS) - return timestamp / 1_000_000; - else if (to == ChronoUnit.MICROS) - return timestamp / 1_000; + if (to == ChronoUnit.SECONDS) return timestamp / 1_000_000_000; + else if (to == ChronoUnit.MILLIS) return timestamp / 1_000_000; + else if (to == ChronoUnit.MICROS) return timestamp / 1_000; } throw new IllegalArgumentException("Not supported conversion from '" + from + "' to '" + to + "'"); } public static byte getBestBinaryTypeForPrecision(final ChronoUnit precision) { - if (precision == ChronoUnit.SECONDS) - return BinaryTypes.TYPE_DATETIME_SECOND; - else if (precision == ChronoUnit.MILLIS) - return BinaryTypes.TYPE_DATETIME; - else if (precision == ChronoUnit.MICROS) - return BinaryTypes.TYPE_DATETIME_MICROS; - else if (precision == ChronoUnit.NANOS) - return BinaryTypes.TYPE_DATETIME_NANOS; + if (precision == ChronoUnit.SECONDS) return BinaryTypes.TYPE_DATETIME_SECOND; + else if (precision == ChronoUnit.MILLIS) return BinaryTypes.TYPE_DATETIME; + else if (precision == ChronoUnit.MICROS) return BinaryTypes.TYPE_DATETIME_MICROS; + else if (precision == ChronoUnit.NANOS) return BinaryTypes.TYPE_DATETIME_NANOS; throw new IllegalArgumentException("Not supported precision '" + precision + "'"); } @@ -309,48 +255,38 @@ public static final ChronoUnit getPrecisionFromBinaryType(final byte type) { } public static int getNanos(final Object obj) { - if (obj == null) - throw new IllegalArgumentException("Object is null"); - else if (obj instanceof LocalDateTime) - return ((LocalDateTime) obj).getNano(); - else if (obj instanceof ZonedDateTime) - return ((ZonedDateTime) obj).getNano(); - else if (obj instanceof Instant) - return ((Instant) obj).getNano(); + if (obj == null) throw new IllegalArgumentException("Object is null"); + else if (obj instanceof LocalDateTime) return ((LocalDateTime) obj).getNano(); + else if (obj instanceof ZonedDateTime) return ((ZonedDateTime) obj).getNano(); + else if (obj instanceof Instant) return ((Instant) obj).getNano(); throw new IllegalArgumentException("Object of class '" + obj.getClass() + "' is not supported"); } public static boolean isDate(final Object obj) { - if (obj == null) - return false; + if (obj == null) return false; return obj instanceof Date || obj instanceof Calendar || obj instanceof LocalDate || obj instanceof LocalDateTime || obj instanceof ZonedDateTime || obj instanceof Instant; } public static ChronoUnit getHigherPrecision(final Object... objs) { - if (objs == null || objs.length == 0) - return null; + if (objs == null || objs.length == 0) return null; ChronoUnit highestPrecision = ChronoUnit.MILLIS; for (int i = 0; i < objs.length; i++) { final Object obj = objs[i]; final ChronoUnit precision; - if (obj instanceof Date || obj instanceof Calendar) - precision = ChronoUnit.MILLIS; + if (obj instanceof Date || obj instanceof Calendar) precision = ChronoUnit.MILLIS; else if (obj instanceof LocalDateTime || obj instanceof ZonedDateTime || obj instanceof Instant) precision = getPrecision(getNanos(obj)); - else - continue; + else continue; - if (precision.compareTo(highestPrecision) < 0) - highestPrecision = precision; + if (precision.compareTo(highestPrecision) < 0) highestPrecision = precision; } return highestPrecision; } public static LocalDateTime millisToLocalDateTime(final long millis, final String timeZone) { - if (timeZone == null) - return Instant.ofEpochMilli(millis).atZone(ZoneId.systemDefault()).toLocalDateTime(); + if (timeZone == null) return Instant.ofEpochMilli(millis).atZone(ZoneId.systemDefault()).toLocalDateTime(); return Instant.ofEpochMilli(millis).atZone(ZoneId.of(timeZone)).toLocalDateTime(); } @@ -363,19 +299,14 @@ public static String format(final Object obj, final String format) { } public static String format(final Object obj, final String format, final String timeZone) { - if (obj instanceof Number) - return getFormatter(format).format(millisToLocalDateTime(((Number) obj).longValue(), timeZone)); - else if (obj instanceof Date) - return getFormatter(format).format(millisToLocalDateTime(((Date) obj).getTime(), timeZone)); + if (obj instanceof Number) return getFormatter(format).format(millisToLocalDateTime(((Number) obj).longValue(), timeZone)); + else if (obj instanceof Date) return getFormatter(format).format(millisToLocalDateTime(((Date) obj).getTime(), timeZone)); else if (obj instanceof Calendar) return getFormatter(format).format(millisToLocalDateTime(((Calendar) obj).getTimeInMillis(), timeZone)); else if (obj instanceof LocalDateTime) { - if (timeZone != null) - return ((LocalDateTime) obj).atZone(ZoneId.of(timeZone)).format(getFormatter(format)); - else - return getFormatter(format).format(((LocalDateTime) obj)); - } else if (obj instanceof TemporalAccessor) - return getFormatter(format).format((TemporalAccessor) obj); + if (timeZone != null) return ((LocalDateTime) obj).atZone(ZoneId.of(timeZone)).format(getFormatter(format)); + else return getFormatter(format).format(((LocalDateTime) obj)); + } else if (obj instanceof TemporalAccessor) return getFormatter(format).format((TemporalAccessor) obj); return null; } @@ -390,8 +321,7 @@ public static DateTimeFormatter getFormatter(final String format) { } public static Object getDate(final Object date, final Class impl) { - if (impl.equals(Date.class)) - return new Date(DateUtils.dateTimeToTimestamp(date, ChronoUnit.MILLIS)); + if (impl.equals(Date.class)) return new Date(DateUtils.dateTimeToTimestamp(date, ChronoUnit.MILLIS)); else if (impl.equals(Calendar.class)) { final Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(DateUtils.dateTimeToTimestamp(date, ChronoUnit.MILLIS)); @@ -401,28 +331,22 @@ else if (impl.equals(Calendar.class)) { } public static String formatElapsed(final long ms) { - if (ms < 1000) - return ms + " ms"; + if (ms < 1000) return ms + " ms"; final long seconds = ms / 1000; - if (seconds < 60) - return seconds + " seconds"; + if (seconds < 60) return seconds + " seconds"; final float minutes = seconds / 60F; - if (minutes < 60F) - return String.format("%.1f minutes", minutes); + if (minutes < 60F) return String.format("%.1f minutes", minutes); final float hours = minutes / 60F; - if (hours < 24F) - return String.format("%.1f hours", hours); + if (hours < 24F) return String.format("%.1f hours", hours); final float days = hours / 24F; - if (days < 30F) - return String.format("%.1f days", days); + if (days < 30F) return String.format("%.1f days", days); final float months = days / 30F; - if (months < 12F) - return String.format("%.1f months", months); + if (months < 12F) return String.format("%.1f months", months); return String.format("%.1f years", months / 12F); } diff --git a/engine/src/test/java/com/arcadedb/TestHelper.java b/engine/src/test/java/com/arcadedb/TestHelper.java index 1ccda4d57d..b318377261 100644 --- a/engine/src/test/java/com/arcadedb/TestHelper.java +++ b/engine/src/test/java/com/arcadedb/TestHelper.java @@ -74,7 +74,33 @@ protected boolean isCheckingDatabaseIntegrity() { } public static void executeInNewDatabase(final DatabaseTest callback) throws Exception { - try (final DatabaseFactory factory = new DatabaseFactory("./target/databases/" + UUID.randomUUID())) { + executeInNewDatabase(UUID.randomUUID().toString(), callback); +// try (final DatabaseFactory factory = new DatabaseFactory("./target/databases/" + UUID.randomUUID())) { +// if (factory.exists()) { +// factory.open().drop(); +// assertThat(DatabaseFactory.getActiveDatabaseInstance(factory.getDatabasePath())).isNull(); +// } +// +// final Database database = factory.create(); +// assertThat(DatabaseFactory.getActiveDatabaseInstance(factory.getDatabasePath())).isEqualTo(database); +// try { +// database.begin(); +// callback.call(database); +// database.commit(); +// } finally { +// if (database.isTransactionActive()) +// database.rollback(); +// database.drop(); +// } +// } + } + + public static DocumentType createRandomType(final Database database) { + return database.getSchema().createDocumentType("RandomType" + new Random().nextInt(100_000)); + } + + public static void executeInNewDatabase(final String testName, final DatabaseTest callback) throws Exception { + try (final DatabaseFactory factory = new DatabaseFactory("./target/databases" + testName)) { if (factory.exists()) { factory.open().drop(); assertThat(DatabaseFactory.getActiveDatabaseInstance(factory.getDatabasePath())).isNull(); @@ -94,26 +120,6 @@ public static void executeInNewDatabase(final DatabaseTest callback) t } } - public static DocumentType createRandomType(final Database database) { - return database.getSchema().createDocumentType("RandomType" + new Random().nextInt(100_000)); - } - - public static void executeInNewDatabase(final String testName, final DatabaseTest callback) throws Exception { - try (final DatabaseFactory factory = new DatabaseFactory("./target/" + testName)) { - if (factory.exists()) - factory.open().drop(); - - final DatabaseInternal database = (DatabaseInternal) factory.create(); - assertThat(DatabaseFactory.getActiveDatabaseInstance(factory.getDatabasePath())).isEqualTo(database); - try { - callback.call(database); - } finally { - database.drop(); - assertThat(DatabaseFactory.getActiveDatabaseInstance(database.getDatabasePath())).isNull(); - } - } - } - public static Database createDatabase(final String databaseName) { return dropDatabase(databaseName).create(); } diff --git a/engine/src/test/java/com/arcadedb/index/LSMTreeIndexTest.java b/engine/src/test/java/com/arcadedb/index/LSMTreeIndexTest.java index f16d9f817e..707970800c 100644 --- a/engine/src/test/java/com/arcadedb/index/LSMTreeIndexTest.java +++ b/engine/src/test/java/com/arcadedb/index/LSMTreeIndexTest.java @@ -509,8 +509,8 @@ public void testUpdateKeys() { int total = 0; final ResultSet resultSet = database.query("sql", "select from " + TYPE_NAME); - for (final ResultSet it = resultSet; it.hasNext(); ) { - final Result r = it.next(); + while (resultSet.hasNext()) { + final Result r = resultSet.next(); assertThat(r.getElement().get().get("id")).isNotNull(); diff --git a/engine/src/test/java/com/arcadedb/query/sql/executor/AlterTypeExecutionTest.java b/engine/src/test/java/com/arcadedb/query/sql/executor/AlterTypeExecutionTest.java index dbb4cf2f9f..bac76d7a99 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/executor/AlterTypeExecutionTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/executor/AlterTypeExecutionTest.java @@ -21,6 +21,7 @@ import com.arcadedb.TestHelper; import com.arcadedb.database.bucketselectionstrategy.BucketSelectionStrategy; import com.arcadedb.database.bucketselectionstrategy.PartitionedBucketSelectionStrategy; +import com.arcadedb.schema.DocumentType; import com.arcadedb.serializer.json.JSONObject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -43,10 +44,10 @@ public void sqlAlterTypeInheritanceUsing() { database.command("sql", "ALTER TYPE Car SUPERTYPE +Vehicle"); assertThat(database.getSchema().getType("Car").getSuperTypes().size()).isEqualTo(1); - assertThat(database.getSchema().getType("Car").getSuperTypes().stream().map(x -> x.getName()).collect(Collectors.toSet()) + assertThat(database.getSchema().getType("Car").getSuperTypes().stream().map(DocumentType::getName).collect(Collectors.toSet()) .contains("Vehicle")).isTrue(); assertThat(database.getSchema().getType("Vehicle").getSubTypes().size()).isEqualTo(1); - assertThat(database.getSchema().getType("Vehicle").getSubTypes().stream().map(x -> x.getName()).collect(Collectors.toSet()) + assertThat(database.getSchema().getType("Vehicle").getSubTypes().stream().map(DocumentType::getName).toList() .contains("Car")).isTrue(); assertThat(database.getSchema().getType("Vehicle").isSuperTypeOf("Car")).isTrue(); @@ -57,7 +58,7 @@ public void sqlAlterTypeInheritanceUsing() { assertThat(database.getSchema().getType("Suv").getSuperTypes().size()).isEqualTo(1); assertThat(database.getSchema().getType("Car").isSuperTypeOf("Suv")).isTrue(); assertThat(database.getSchema().getType("Car").getSubTypes().size()).isEqualTo(1); - assertThat(database.getSchema().getType("Car").getSubTypes().stream().map(x -> x.getName()).collect(Collectors.toSet()) + assertThat(database.getSchema().getType("Car").getSubTypes().stream().map(DocumentType::getName).collect(Collectors.toSet()) .contains("Suv")).isTrue(); assertThat(database.getSchema().getType("Car").isSuperTypeOf("Suv")).isTrue(); @@ -71,7 +72,7 @@ public void sqlAlterTypeInheritanceUsing() { assertThat(database.getSchema().getType("Vehicle").isSuperTypeOf("Suv")).isTrue(); assertThat(database.getSchema().getType("Car").getSubTypes().size()).isEqualTo(1); assertThat(database.getSchema().getType("Vehicle").getSubTypes().size()).isEqualTo(1); - assertThat(database.getSchema().getType("Car").getSubTypes().stream().map(x -> x.getName()).collect(Collectors.toSet()) + assertThat(database.getSchema().getType("Car").getSubTypes().stream().map(DocumentType::getName).collect(Collectors.toSet()) .contains("Suv")).isTrue(); assertThat(database.getSchema().getType("Car").isSuperTypeOf("Suv")).isTrue(); assertThat(database.getSchema().getType("Vehicle").isSuperTypeOf("Suv")).isTrue(); diff --git a/engine/src/test/java/com/arcadedb/query/sql/executor/BeginStatementExecutionTest.java b/engine/src/test/java/com/arcadedb/query/sql/executor/BeginStatementExecutionTest.java index ce3e42c268..ca1690f0bf 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/executor/BeginStatementExecutionTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/executor/BeginStatementExecutionTest.java @@ -32,8 +32,8 @@ public class BeginStatementExecutionTest { @Test public void testBegin() throws Exception { - TestHelper.executeInNewDatabase("OCommitStatementExecutionTest", (db) -> { - assertThat(db.getTransaction() == null || !db.getTransaction().isActive()).isTrue(); + TestHelper.executeInNewDatabase( (db) -> { + assertThat(db.isTransactionActive()).isTrue(); final ResultSet result = db.command("sql", "begin"); //printExecutionPlan(null, result); assertThat((Iterator) result).isNotNull(); @@ -41,8 +41,8 @@ public void testBegin() throws Exception { final Result item = result.next(); assertThat(item.getProperty("operation")).isEqualTo("begin"); assertThat(result.hasNext()).isFalse(); - assertThat(db.getTransaction() == null || !db.getTransaction().isActive()).isFalse(); db.commit(); +// assertThat(db.isTransactionActive()).isFalse(); }); } } diff --git a/engine/src/test/java/com/arcadedb/query/sql/executor/CreateVertexStatementExecutionTest.java b/engine/src/test/java/com/arcadedb/query/sql/executor/CreateVertexStatementExecutionTest.java index e0af3143b9..975e3a0718 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/executor/CreateVertexStatementExecutionTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/executor/CreateVertexStatementExecutionTest.java @@ -25,6 +25,8 @@ import org.junit.jupiter.api.Test; import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; @@ -40,24 +42,19 @@ public CreateVertexStatementExecutionTest() { @Test public void testVerticesContentJsonArray() { final String className = "testVertexContentArray"; - database.getSchema().createVertexType(className, 1); - - String array = "["; - for (int i = 0; i < 1000; i++) { - if (i > 0) - array += ","; - array += "{'name':'name" + i + "', 'surname':'surname" + i + "'}"; - } - array += "]"; + database.getSchema().buildVertexType().withName(className).withTotalBuckets(1).create(); + String array = IntStream.range(0, 1000) + .mapToObj(i -> String.format("{'name':'name%d', 'surname':'surname%d'}", i, i)) + .collect(Collectors.joining(",", "[", "]")); ResultSet result = database.command("sql", "create vertex " + className + " content " + array); for (int i = 0; i < 1000; i++) { assertThat(result.hasNext()).isTrue(); final Result item = result.next(); assertThat(item).isNotNull(); - assertThat(item.getProperty("name").toString()).isEqualTo("name" + i); - assertThat(item.getProperty("surname").toString()).isEqualTo("surname" + i); + assertThat(item.getProperty("name")).isEqualTo("name" + i); + assertThat(item.getProperty("surname")).isEqualTo("surname" + i); } assertThat(result.hasNext()).isFalse(); @@ -67,8 +64,8 @@ public void testVerticesContentJsonArray() { assertThat(result.hasNext()).isTrue(); Result item = result.next(); assertThat(item).isNotNull(); - assertThat(item.getProperty("name").toString()).isEqualTo("name" + i); - assertThat(item.getProperty("surname").toString()).isEqualTo("surname" + i); + assertThat(item.getProperty("name")).isEqualTo("name" + i); + assertThat(item.getProperty("surname")).isEqualTo("surname" + i); } assertThat(result.hasNext()).isFalse(); diff --git a/engine/src/test/java/com/arcadedb/query/sql/executor/GroupByExecutionTest.java b/engine/src/test/java/com/arcadedb/query/sql/executor/GroupByExecutionTest.java index 3479019da2..4d683e89f2 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/executor/GroupByExecutionTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/executor/GroupByExecutionTest.java @@ -48,7 +48,12 @@ public void testGroupByCount() { } } - final ResultSet result = database.query("sql", "select address, count(*) as occurrences from InputTx where address is not null group by address limit 10"); + final ResultSet result = database.query("sql", """ + select address, count(*) as occurrences + from InputTx where address is not null + group by address + limit 10 + """); while (result.hasNext()) { final Result row = result.next(); assertThat(row.getProperty("address")).isNotNull(); diff --git a/engine/src/test/java/com/arcadedb/query/sql/executor/MatchInheritanceTest.java b/engine/src/test/java/com/arcadedb/query/sql/executor/MatchInheritanceTest.java index 5fb7d08056..5e2dc04394 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/executor/MatchInheritanceTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/executor/MatchInheritanceTest.java @@ -11,9 +11,7 @@ public class MatchInheritanceTest extends TestHelper { public void testInheritance() { ResultSet result = null; - String sql = "SELECT FROM Services"; - - result = database.command("SQL", sql); + result = database.command("SQL", "SELECT FROM Services"); int selectFromServices = 0; while (result.hasNext()) { Result record = result.next(); @@ -21,8 +19,7 @@ public void testInheritance() { } assertThat(selectFromServices).isEqualTo(4); - sql = "SELECT FROM Attractions"; - result = database.command("SQL", sql); + result = database.command("SQL", "SELECT FROM Attractions"); int selectFromAttractions = 0; while (result.hasNext()) { Result record = result.next(); @@ -30,9 +27,7 @@ public void testInheritance() { } assertThat(selectFromAttractions).isEqualTo(4); - sql = "SELECT FROM Locations"; - - result = database.command("SQL", sql); + result = database.command("SQL", "SELECT FROM Locations"); int selectFromLocations = 0; while (result.hasNext()) { Result record = result.next(); @@ -40,32 +35,29 @@ public void testInheritance() { } assertThat(selectFromLocations).isEqualTo(8); - sql = "MATCH {type: Customers, as: customer, where: (OrderedId=1)}--{type: Monuments} " + "RETURN $pathelements"; - result = database.query("SQL", sql); + result = database.query("SQL", + "MATCH {type: Customers, as: customer, where: (OrderedId=1)}--{type: Monuments} RETURN $pathelements"); assertThat(result.stream().count()).isEqualTo(2); - sql = "MATCH {type: Customers, as: customer, where: (OrderedId=1)}--{type: Services} " + "RETURN $pathelements"; - result = database.query("SQL", sql); + result = database.query("SQL", + "MATCH {type: Customers, as: customer, where: (OrderedId=1)}--{type: Services} RETURN $pathelements"); assertThat(result.stream().count()).isEqualTo(8); - sql = "MATCH {type: Customers, as: customer, where: (OrderedId=1)}--{type: Attractions} " + "RETURN $pathelements"; - result = database.query("SQL", sql); + result = database.query("SQL", + "MATCH {type: Customers, as: customer, where: (OrderedId=1)}--{type: Attractions} RETURN $pathelements"); assertThat(result.stream().count()).isEqualTo(8); - sql = "MATCH {type: Customers, as: customer, where: (OrderedId=1)}--{type: Locations} " + "RETURN $pathelements"; - result = database.query("SQL", sql); + result = database.query("SQL", + "MATCH {type: Customers, as: customer, where: (OrderedId=1)}--{type: Locations} RETURN $pathelements"); assertThat(result.stream().count()).isEqualTo(16); } @Override public void beginTest() { - StringBuilder sb = new StringBuilder(); - - sb.append("BEGIN;"); /* -- Locations -- + Services @@ -77,95 +69,96 @@ public void beginTest() { -- + Theatres -- + Archaeological Sites */ - sb.append("CREATE VERTEX TYPE Locations;"); - sb.append("CREATE PROPERTY Locations.Id LONG;"); - sb.append("CREATE PROPERTY Locations.Type STRING;"); - sb.append("CREATE PROPERTY Locations.Name STRING;"); - - sb.append("CREATE INDEX ON Locations (Type) NOTUNIQUE;"); - sb.append("CREATE INDEX ON Locations (Name) FULL_TEXT;"); +String sqlScript = """ + BEGIN; + CREATE VERTEX TYPE Locations; + CREATE PROPERTY Locations.Id LONG; + CREATE PROPERTY Locations.Type STRING; + CREATE PROPERTY Locations.Name STRING; - sb.append("CREATE VERTEX TYPE Services EXTENDS Locations;"); - sb.append("CREATE VERTEX TYPE Hotels EXTENDS Services;"); - sb.append("CREATE INDEX ON Hotels (Id) UNIQUE;"); + CREATE INDEX ON Locations (Type) NOTUNIQUE; + CREATE INDEX ON Locations (Name) FULL_TEXT; - sb.append("CREATE VERTEX TYPE Restaurants EXTENDS Services;\n"); - sb.append("CREATE INDEX ON Restaurants(Id) UNIQUE;\n"); + CREATE VERTEX TYPE Services EXTENDS Locations; + CREATE VERTEX TYPE Hotels EXTENDS Services; + CREATE INDEX ON Hotels (Id) UNIQUE; - sb.append("CREATE VERTEX TYPE Attractions EXTENDS Locations;\n"); - sb.append("CREATE VERTEX TYPE Monuments EXTENDS Attractions;\n"); - sb.append("CREATE INDEX ON Monuments (Id) UNIQUE;\n"); + CREATE VERTEX TYPE Restaurants EXTENDS Services; + CREATE INDEX ON Restaurants(Id) UNIQUE; - sb.append("CREATE VERTEX TYPE Castles EXTENDS Attractions;\n"); - sb.append("CREATE INDEX ON Castles(Id) UNIQUE;\n"); + CREATE VERTEX TYPE Attractions EXTENDS Locations; + CREATE VERTEX TYPE Monuments EXTENDS Attractions; + CREATE INDEX ON Monuments (Id) UNIQUE; - sb.append("CREATE VERTEX TYPE Theatres EXTENDS Attractions;\n"); - sb.append("CREATE INDEX ON Theatres(Id) UNIQUE;\n"); + CREATE VERTEX TYPE Castles EXTENDS Attractions; + CREATE INDEX ON Castles(Id) UNIQUE; - sb.append("CREATE VERTEX TYPE ArchaeologicalSites EXTENDS Attractions;\n"); - sb.append("CREATE INDEX ON ArchaeologicalSites(Id) UNIQUE;\n"); + CREATE VERTEX TYPE Theatres EXTENDS Attractions; + CREATE INDEX ON Theatres(Id) UNIQUE; - sb.append("CREATE VERTEX TYPE Customers;"); - sb.append("CREATE PROPERTY Customers.OrderedId LONG;"); + CREATE VERTEX TYPE ArchaeologicalSites EXTENDS Attractions; + CREATE INDEX ON ArchaeologicalSites(Id) UNIQUE; - sb.append("CREATE VERTEX TYPE Orders;"); - sb.append("CREATE PROPERTY Orders.Id LONG;"); - sb.append("CREATE PROPERTY Orders.Amount LONG;"); - sb.append("CREATE PROPERTY Orders.OrderDate DATE;"); + CREATE VERTEX TYPE Customers; + CREATE PROPERTY Customers.OrderedId LONG; - sb.append("CREATE INDEX ON Customers(OrderedId) UNIQUE;"); + CREATE VERTEX TYPE Orders; + CREATE PROPERTY Orders.Id LONG; + CREATE PROPERTY Orders.Amount LONG; + CREATE PROPERTY Orders.OrderDate DATE; - sb.append("CREATE INDEX ON Orders(Id) UNIQUE;"); + CREATE INDEX ON Customers(OrderedId) UNIQUE; - sb.append("CREATE EDGE TYPE HasUsedService;"); - sb.append("CREATE PROPERTY HasUsedService.out LINK OF Customers;"); + CREATE INDEX ON Orders(Id) UNIQUE; - sb.append("CREATE EDGE TYPE HasStayed EXTENDS HasUsedService;"); - sb.append("CREATE PROPERTY HasStayed.in LINK OF Hotels;"); + CREATE EDGE TYPE HasUsedService; + CREATE PROPERTY HasUsedService.out LINK OF Customers; - sb.append("CREATE EDGE TYPE HasEaten EXTENDS HasUsedService;"); - sb.append("CREATE PROPERTY HasEaten.in LINK OF Restaurants;"); + CREATE EDGE TYPE HasStayed EXTENDS HasUsedService; + CREATE PROPERTY HasStayed.in LINK OF Hotels; - sb.append("CREATE EDGE TYPE HasVisited;"); - sb.append("CREATE PROPERTY HasVisited.out LINK OF Customers;"); - sb.append("CREATE PROPERTY HasVisited.in LINK;"); - sb.append("CREATE INDEX ON HasVisited (`in`, `out`) UNIQUE;"); + CREATE EDGE TYPE HasEaten EXTENDS HasUsedService; + CREATE PROPERTY HasEaten.in LINK OF Restaurants; - sb.append("CREATE EDGE TYPE HasCustomer;"); - sb.append("CREATE PROPERTY HasCustomer.in LINK OF Customers;"); - sb.append("CREATE PROPERTY HasCustomer.out LINK OF Orders ;"); + CREATE EDGE TYPE HasVisited; + CREATE PROPERTY HasVisited.out LINK OF Customers; + CREATE PROPERTY HasVisited.in LINK; + CREATE INDEX ON HasVisited (`in`, `out`) UNIQUE; - sb.append("INSERT INTO Customers SET OrderedId = 1, Phone = '+1400844724';"); - sb.append("INSERT INTO Orders SET Id = 1, Amount = 536, OrderDate = '2013-05-23';"); + CREATE EDGE TYPE HasCustomer; + CREATE PROPERTY HasCustomer.in LINK OF Customers; + CREATE PROPERTY HasCustomer.out LINK OF Orders; - sb.append("INSERT INTO Hotels SET Id = 730, Name = 'Toules', Type = 'alpine_hut';"); + INSERT INTO Customers SET OrderedId = 1, Phone = '+1400844724'; + INSERT INTO Orders SET Id = 1, Amount = 536, OrderDate = '2013-05-23'; - sb.append("INSERT INTO Restaurants SET Id = 1834, Name = 'Uliassi', Type = 'restaurant';"); - sb.append("INSERT INTO Restaurants SET Id = 1099, Name = 'L\\'Angelo d\\'Oro', Type = 'restaurant';"); + INSERT INTO Hotels SET Id = 730, Name = 'Toules', Type = 'alpine_hut'; - sb.append("INSERT INTO Restaurants SET Id = 1738, Name = 'Johnny Paranza', Type = 'fast_food';"); + INSERT INTO Restaurants SET Id = 1834, Name = 'Uliassi', Type = 'restaurant'; + INSERT INTO Restaurants SET Id = 1099, Name = 'L\\'Angelo d\\'Oro', Type = 'restaurant'; - sb.append("INSERT INTO Castles SET Id = 127, Name = 'Haselburg', Type = 'castle';"); - sb.append("INSERT INTO ArchaeologicalSites SET Id = 47, Name = 'Villa Romana', Type = 'archaeological_site';"); - sb.append("INSERT INTO Monuments SET Id = 62, Name = 'Giuseppe Garibaldi', Type = 'monument';"); - sb.append("INSERT INTO Theatres SET Id = 65, Name = 'Teatro Civico', Type = 'theatre';"); + INSERT INTO Restaurants SET Id = 1738, Name = 'Johnny Paranza', Type = 'fast_food'; - sb.append("CREATE EDGE HasStayed FROM (SELECT FROM Customers WHERE OrderedId=1) TO (SELECT FROM Hotels WHERE Id=730);"); + INSERT INTO Castles SET Id = 127, Name = 'Haselburg', Type = 'castle'; + INSERT INTO ArchaeologicalSites SET Id = 47, Name = 'Villa Romana', Type = 'archaeological_site'; + INSERT INTO Monuments SET Id = 62, Name = 'Giuseppe Garibaldi', Type = 'monument'; + INSERT INTO Theatres SET Id = 65, Name = 'Teatro Civico', Type = 'theatre'; - sb.append("CREATE EDGE HasEaten FROM (SELECT FROM Customers WHERE OrderedId=1) TO (SELECT FROM Restaurants WHERE Id=1834);"); - sb.append("CREATE EDGE HasEaten FROM (SELECT FROM Customers WHERE OrderedId=1) TO (SELECT FROM Restaurants WHERE Id=1099);"); - sb.append("CREATE EDGE HasEaten FROM (SELECT FROM Customers WHERE OrderedId=1) TO (SELECT FROM Restaurants WHERE Id=1738);"); + CREATE EDGE HasStayed FROM (SELECT FROM Customers WHERE OrderedId=1) TO (SELECT FROM Hotels WHERE Id=730); - sb.append("CREATE EDGE HasCustomer FROM (SELECT FROM Orders WHERE Id=1) TO (SELECT FROM Customers WHERE OrderedId=1);"); + CREATE EDGE HasEaten FROM (SELECT FROM Customers WHERE OrderedId=1) TO (SELECT FROM Restaurants WHERE Id=1834); + CREATE EDGE HasEaten FROM (SELECT FROM Customers WHERE OrderedId=1) TO (SELECT FROM Restaurants WHERE Id=1099); + CREATE EDGE HasEaten FROM (SELECT FROM Customers WHERE OrderedId=1) TO (SELECT FROM Restaurants WHERE Id=1738); - sb.append("CREATE EDGE HasVisited FROM (SELECT FROM Customers WHERE OrderedId=1) TO (SELECT FROM Castles WHERE Id=127);"); - sb.append( - "CREATE EDGE HasVisited FROM (SELECT FROM Customers WHERE OrderedId=1) TO (SELECT FROM ArchaeologicalSites WHERE Id=47);"); - sb.append("CREATE EDGE HasVisited FROM (SELECT FROM Customers WHERE OrderedId=1) TO (SELECT FROM Monuments WHERE Id=62);"); - sb.append("CREATE EDGE HasVisited FROM (SELECT FROM Customers WHERE OrderedId=1) TO (SELECT FROM Theatres WHERE Id=65);"); + CREATE EDGE HasCustomer FROM (SELECT FROM Orders WHERE Id=1) TO (SELECT FROM Customers WHERE OrderedId=1); - sb.append("COMMIT;"); + CREATE EDGE HasVisited FROM (SELECT FROM Customers WHERE OrderedId=1) TO (SELECT FROM Castles WHERE Id=127); + CREATE EDGE HasVisited FROM (SELECT FROM Customers WHERE OrderedId=1) TO (SELECT FROM ArchaeologicalSites WHERE Id=47); + CREATE EDGE HasVisited FROM (SELECT FROM Customers WHERE OrderedId=1) TO (SELECT FROM Monuments WHERE Id=62); + CREATE EDGE HasVisited FROM (SELECT FROM Customers WHERE OrderedId=1) TO (SELECT FROM Theatres WHERE Id=65); - database.command("SQLScript", sb.toString()); + COMMIT; + """; + database.command("SQLScript", sqlScript); } } diff --git a/engine/src/test/java/com/arcadedb/query/sql/executor/MatchResultTest.java b/engine/src/test/java/com/arcadedb/query/sql/executor/MatchResultTest.java index fa0059400f..41d3781817 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/executor/MatchResultTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/executor/MatchResultTest.java @@ -17,24 +17,23 @@ public class MatchResultTest extends TestHelper { */ @Test public void testIssue1689() { - database.transaction(() -> database.command("sqlscript", "CREATE VERTEX TYPE Person IF NOT EXISTS;\n" - + "CREATE PROPERTY Person.role IF NOT EXISTS STRING;\n" - + "CREATE VERTEX TYPE House IF NOT EXISTS;\n" - + "CREATE EDGE TYPE LivesIn IF NOT EXISTS;\n" -// + "CREATE EDGE TYPE DummyEdge IF NOT EXISTS;\n" -// + "DELETE FROM LivesIn;\n" -// + "DELETE FROM Person;\n" -// + "DELETE FROM House;\n" - + "CREATE VERTEX House;\n" - + "CREATE VERTEX Person SET role='mom';\n" - + "CREATE VERTEX Person SET role='dad';\n" - + "CREATE VERTEX Person SET role='child';\n" - + "CREATE EDGE LivesIn FROM (SELECT FROM Person) TO (SELECT FROM House);")); - - final ResultSet resultSet = database.query("sql", "MATCH {TYPE: Person, AS: personVertex} -LivesIn-> {TYPE: House}\n" - + ", NOT {AS: personVertex} -DummyEdge-> {TYPE: House}\n" - + "RETURN personVertex"); - +database.transaction(() -> database.command("sqlscript", """ + CREATE VERTEX TYPE Person IF NOT EXISTS; + CREATE PROPERTY Person.role IF NOT EXISTS STRING; + CREATE VERTEX TYPE House IF NOT EXISTS; + CREATE EDGE TYPE LivesIn IF NOT EXISTS; + CREATE VERTEX House; + CREATE VERTEX Person SET role='mom'; + CREATE VERTEX Person SET role='dad'; + CREATE VERTEX Person SET role='child'; + CREATE EDGE LivesIn FROM (SELECT FROM Person) TO (SELECT FROM House); + """)); + +final ResultSet resultSet = database.query("sql", """ + MATCH {TYPE: Person, AS: personVertex} -LivesIn-> {TYPE: House} + , NOT {AS: personVertex} -DummyEdge-> {TYPE: House} + RETURN personVertex + """); Set set = new HashSet<>(); while (resultSet.hasNext()) { final Vertex next = resultSet.nextIfAvailable().getProperty("personVertex"); diff --git a/engine/src/test/java/com/arcadedb/query/sql/executor/MatchStatementExecutionTest.java b/engine/src/test/java/com/arcadedb/query/sql/executor/MatchStatementExecutionTest.java index d02de5fe64..13a1af4e1e 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/executor/MatchStatementExecutionTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/executor/MatchStatementExecutionTest.java @@ -22,6 +22,7 @@ import com.arcadedb.database.*; import com.arcadedb.graph.MutableVertex; import com.arcadedb.graph.Vertex; +import com.arcadedb.index.Index; import com.arcadedb.index.TypeIndex; import org.junit.jupiter.api.Test; @@ -926,17 +927,18 @@ public void testManagedArrows() { } private ResultSet getManagedByArrows(final String managerName) { - final StringBuilder query = new StringBuilder(); - query.append("select expand(managed) from ("); - query.append(" match {type:Employee, where: (name = '" + managerName + "')}"); - query.append(" -ManagerOf->{}<-ParentDepartment-{"); - query.append(" while: ($depth = 0 or in('ManagerOf').size() = 0),"); - query.append(" where: ($depth = 0 or in('ManagerOf').size() = 0)"); - query.append(" }<-WorksAt-{as: managed}"); - query.append(" return managed"); - query.append(")"); + final String query = """ + select expand(managed) from ( + match {type:Employee, where: (name = '%s')} + -ManagerOf->{}<-ParentDepartment-{ + while: ($depth = 0 or in('ManagerOf').size() = 0), + where: ($depth = 0 or in('ManagerOf').size() = 0) + }<-WorksAt-{as: managed} + return managed + ) + """.formatted(managerName); - return database.query("sql", query.toString()); + return database.query("sql", query); } @Test @@ -969,19 +971,20 @@ public void testManaged2() { } private ResultSet getManagedBy2(final String managerName) { - final StringBuilder query = new StringBuilder(); - query.append("select expand(managed) from ("); - query.append(" match {type:Employee, where: (name = '" + managerName + "')}"); - query.append(" .out('ManagerOf')"); - query.append(" .(inE('ParentDepartment').outV()){"); - query.append(" while: ($depth = 0 or in('ManagerOf').size() = 0),"); - query.append(" where: ($depth = 0 or in('ManagerOf').size() = 0)"); - query.append(" }"); - query.append(" .in('WorksAt'){as: managed}"); - query.append(" return managed"); - query.append(")"); + final String query = """ + select expand(managed) from ( + match {type:Employee, where: (name = '%s')} + .out('ManagerOf') + .(inE('ParentDepartment').outV()){ + while: ($depth = 0 or in('ManagerOf').size() = 0), + where: ($depth = 0 or in('ManagerOf').size() = 0) + } + .in('WorksAt'){as: managed} + return managed + ) + """.formatted(managerName); - return database.query("sql", query.toString()); + return database.query("sql", query); } @Test @@ -1014,33 +1017,33 @@ public void testManaged2Arrows() { } private ResultSet getManagedBy2Arrows(final String managerName) { - final StringBuilder query = new StringBuilder(); - query.append("select expand(managed) from ("); - query.append(" match {type:Employee, where: (name = '" + managerName + "')}"); - query.append(" -ManagerOf->{}"); - query.append(" .(inE('ParentDepartment').outV()){"); - query.append(" while: ($depth = 0 or in('ManagerOf').size() = 0),"); - query.append(" where: ($depth = 0 or in('ManagerOf').size() = 0)"); - query.append(" }<-WorksAt-{as: managed}"); - query.append(" return managed"); - query.append(")"); + final String query = """ + select expand(managed) from ( + match {type:Employee, where: (name = '%s')} + -ManagerOf->{} + .(inE('ParentDepartment').outV()){ + while: ($depth = 0 or in('ManagerOf').size() = 0), + where: ($depth = 0 or in('ManagerOf').size() = 0) + }<-WorksAt-{as: managed} + return managed + ) + """.formatted(managerName); - return database.query("sql", query.toString()); + return database.query("sql", query); } @Test public void testTriangle1() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:TriangleV, as: friend1, where: (uid = 0)}"); - query.append(" .out('TriangleE'){as: friend2}"); - query.append(" .out('TriangleE'){as: friend3},"); - query.append("{type:TriangleV, as: friend1}"); - query.append(" .out('TriangleE'){as: friend3}"); - query.append("return $matches"); - - final ResultSet result = database.query("sql", query.toString()); + final String query = """ + match {type:TriangleV, as: friend1, where: (uid = 0)} + .out('TriangleE'){as: friend2} + .out('TriangleE'){as: friend3}, + {type:TriangleV, as: friend1} + .out('TriangleE'){as: friend3} + return $matches + """; + final ResultSet result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); result.next(); assertThat(result.hasNext()).isFalse(); @@ -1049,13 +1052,14 @@ public void testTriangle1() { @Test public void testTriangle1Arrows() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:TriangleV, as: friend1, where: (uid = 0)} -TriangleE-> {as: friend2} -TriangleE-> {as: friend3},"); - query.append("{type:TriangleV, as: friend1} -TriangleE-> {as: friend3}"); - query.append("return $matches"); + final String query = """ + match {type:TriangleV, as: friend1, where: (uid = 0)} -TriangleE-> {as: friend2} -TriangleE-> {as: friend3}, + {type:TriangleV, as: friend1} -TriangleE-> {as: friend3} + return $matches + """; - final ResultSet result = database.query("sql", query.toString()); + final ResultSet result = database.query("sql", query); + assertThat(result.hasNext()).isTrue(); assertThat(result.hasNext()).isTrue(); result.next(); assertThat(result.hasNext()).isFalse(); @@ -1064,17 +1068,16 @@ public void testTriangle1Arrows() { @Test public void testTriangle2Old() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:TriangleV, as: friend1}"); - query.append(" .out('TriangleE'){type:TriangleV, as: friend2, where: (uid = 1)}"); - query.append(" .out('TriangleE'){as: friend3},"); - query.append("{type:TriangleV, as: friend1}"); - query.append(" .out('TriangleE'){as: friend3}"); - query.append("return $matches"); - - final ResultSet result = database.query("sql", query.toString()); + final String query = """ + match {type:TriangleV, as: friend1} + .out('TriangleE'){type:TriangleV, as: friend2, where: (uid = 1)} + .out('TriangleE'){as: friend3}, + {type:TriangleV, as: friend1} + .out('TriangleE'){as: friend3} + return $matches + """; + final ResultSet result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); final Result doc = result.next(); final Document friend1 = doc.getProperty("friend1"); @@ -1088,16 +1091,17 @@ public void testTriangle2Old() { @Test public void testTriangle2() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:TriangleV, as: friend1}"); - query.append(" .out('TriangleE'){type:TriangleV, as: friend2, where: (uid = 1)}"); - query.append(" .out('TriangleE'){as: friend3},"); - query.append("{type:TriangleV, as: friend1}"); - query.append(" .out('TriangleE'){as: friend3}"); - query.append("return $patterns"); + final String query = """ + match {type:TriangleV, as: friend1} + .out('TriangleE'){type:TriangleV, as: friend2, where: (uid = 1)} + .out('TriangleE'){as: friend3}, + {type:TriangleV, as: friend1} + .out('TriangleE'){as: friend3} + return $patterns + """; - final ResultSet result = database.query("sql", query.toString()); + final ResultSet result = database.query("sql", query); + assertThat(result.hasNext()).isTrue(); assertThat(result.hasNext()).isTrue(); final Result doc = result.next(); assertThat(result.hasNext()).isFalse(); @@ -1112,16 +1116,17 @@ public void testTriangle2() { @Test public void testTriangle2Arrows() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:TriangleV, as: friend1}"); - query.append(" -TriangleE->{type:TriangleV, as: friend2, where: (uid = 1)}"); - query.append(" -TriangleE->{as: friend3},"); - query.append("{type:TriangleV, as: friend1}"); - query.append(" -TriangleE->{as: friend3}"); - query.append("return $matches"); + final String query = """ + match {type:TriangleV, as: friend1} + -TriangleE->{type:TriangleV, as: friend2, where: (uid = 1)} + -TriangleE->{as: friend3}, + {type:TriangleV, as: friend1} + -TriangleE->{as: friend3} + return $matches + """; - final ResultSet result = database.query("sql", query.toString()); + final ResultSet result = database.query("sql", query); + assertThat(result.hasNext()).isTrue(); assertThat(result.hasNext()).isTrue(); final Result doc = result.next(); assertThat(result.hasNext()).isFalse(); @@ -1136,16 +1141,16 @@ public void testTriangle2Arrows() { @Test public void testTriangle3() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:TriangleV, as: friend1}"); - query.append(" -TriangleE->{as: friend2}"); - query.append(" -TriangleE->{as: friend3, where: (uid = 2)},"); - query.append("{type:TriangleV, as: friend1}"); - query.append(" -TriangleE->{as: friend3}"); - query.append("return $matches"); + final String query = """ + match {type:TriangleV, as: friend1} + -TriangleE->{as: friend2} + -TriangleE->{as: friend3, where: (uid = 2)}, + {type:TriangleV, as: friend1} + -TriangleE->{as: friend3} + return $matches + """; - final ResultSet result = database.query("sql", query.toString()); + final ResultSet result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); final Result doc = result.next(); assertThat(result.hasNext()).isFalse(); @@ -1154,16 +1159,17 @@ public void testTriangle3() { @Test public void testTriangle4() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:TriangleV, as: friend1}"); - query.append(" .out('TriangleE'){as: friend2, where: (uid = 1)}"); - query.append(" .out('TriangleE'){as: friend3},"); - query.append("{type:TriangleV, as: friend1}"); - query.append(" .out('TriangleE'){as: friend3}"); - query.append("return $matches"); + final String query = """ + match {type:TriangleV, as: friend1} + .out('TriangleE'){as: friend2, where: (uid = 1)} + .out('TriangleE'){as: friend3}, + {type:TriangleV, as: friend1} + .out('TriangleE'){as: friend3} + return $matches + """; - final ResultSet result = database.query("sql", query.toString()); + final ResultSet result = database.query("sql", query); + assertThat(result.hasNext()).isTrue(); assertThat(result.hasNext()).isTrue(); final Result doc = result.next(); assertThat(result.hasNext()).isFalse(); @@ -1172,16 +1178,17 @@ public void testTriangle4() { @Test public void testTriangle4Arrows() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:TriangleV, as: friend1}"); - query.append(" -TriangleE->{as: friend2, where: (uid = 1)}"); - query.append(" -TriangleE->{as: friend3},"); - query.append("{type:TriangleV, as: friend1}"); - query.append(" -TriangleE->{as: friend3}"); - query.append("return $matches"); + final String query = """ + match {type:TriangleV, as: friend1} + -TriangleE->{as: friend2, where: (uid = 1)} + -TriangleE->{as: friend3}, + {type:TriangleV, as: friend1} + -TriangleE->{as: friend3} + return $matches + """; - final ResultSet result = database.query("sql", query.toString()); + final ResultSet result = database.query("sql", query); + assertThat(result.hasNext()).isTrue(); assertThat(result.hasNext()).isTrue(); final Result doc = result.next(); assertThat(result.hasNext()).isFalse(); @@ -1190,17 +1197,16 @@ public void testTriangle4Arrows() { @Test public void testTriangleWithEdges4() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:TriangleV, as: friend1}"); - query.append(" .outE('TriangleE').inV(){as: friend2, where: (uid = 1)}"); - query.append(" .outE('TriangleE').inV(){as: friend3},"); - query.append("{type:TriangleV, as: friend1}"); - query.append(" .outE('TriangleE').inV(){as: friend3}"); - query.append("return $matches"); - - final ResultSet result = database.query("sql", query.toString()); + final String query = """ + match {type:TriangleV, as: friend1} + .outE('TriangleE').inV(){as: friend2, where: (uid = 1)} + .outE('TriangleE').inV(){as: friend3}, + {type:TriangleV, as: friend1} + .outE('TriangleE').inV(){as: friend3} + return $matches + """; + final ResultSet result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); final Result doc = result.next(); assertThat(result.hasNext()).isFalse(); @@ -1209,14 +1215,13 @@ public void testTriangleWithEdges4() { @Test public void testCartesianProduct() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:TriangleV, as: friend1, where:(uid = 1)},"); - query.append("{type:TriangleV, as: friend2, where:(uid = 2 or uid = 3)}"); - query.append("return $matches"); - - final ResultSet result = database.query("sql", query.toString()); + final String query = """ + match {type:TriangleV, as: friend1, where:(uid = 1)}, + {type:TriangleV, as: friend2, where:(uid = 2 or uid = 3)} + return $matches + """; + final ResultSet result = database.query("sql", query); for (int i = 0; i < 2; i++) { assertThat(result.hasNext()).isTrue(); final Result doc = result.next(); @@ -1229,13 +1234,12 @@ public void testCartesianProduct() { @Test public void testNoPrefetch() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:IndexedVertex, as: one}"); - query.append("return $patterns"); - - final ResultSet result = database.query("sql", query.toString()); + final String query = """ + match {type:IndexedVertex, as: one} + return $patterns + """; + final ResultSet result = database.query("sql", query); result.getExecutionPlan() .ifPresent(x -> x.getSteps().stream().filter(y -> y instanceof MatchPrefetchStep).forEach(prefetchStepFound -> fail())); @@ -1249,14 +1253,13 @@ public void testNoPrefetch() { @Test public void testCartesianProductLimit() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:TriangleV, as: friend1, where:(uid = 1)},"); - query.append("{type:TriangleV, as: friend2, where:(uid = 2 or uid = 3)}"); - query.append("return $matches LIMIT 1"); - - final ResultSet result = database.query("sql", query.toString()); + final String query = """ + match {type:TriangleV, as: friend1, where:(uid = 1)}, + {type:TriangleV, as: friend2, where:(uid = 2 or uid = 3)} + return $matches LIMIT 1 + """; + final ResultSet result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); final Result d = result.next(); final Document friend1 = d.getProperty("friend1"); @@ -1322,12 +1325,12 @@ public void testArrayRangeSelectors1() { @Test public void testArrayRange2() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:TriangleV, as: friend1, where: (uid = 0)}"); - query.append("return friend1.out('TriangleE')[0..2] as foo"); + final String query = """ + match {type:TriangleV, as: friend1, where: (uid = 0)} + return friend1.out('TriangleE')[0..2] as foo + """; - final ResultSet result = database.query("sql", query.toString()); + final ResultSet result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); final Result doc = result.next(); assertThat(result.hasNext()).isFalse(); @@ -1341,12 +1344,12 @@ public void testArrayRange2() { @Test public void testArrayRange3() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:TriangleV, as: friend1, where: (uid = 0)}"); - query.append("return friend1.out('TriangleE')[0..3] as foo"); + final String query = """ + match {type:TriangleV, as: friend1, where: (uid = 0)} + return friend1.out('TriangleE')[0..3] as foo + """; - final ResultSet result = database.query("sql", query.toString()); + final ResultSet result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); final Result doc = result.next(); assertThat(result.hasNext()).isFalse(); @@ -1360,12 +1363,12 @@ public void testArrayRange3() { @Test public void testConditionInSquareBrackets() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:TriangleV, as: friend1, where: (uid = 0)}"); - query.append("return friend1.out('TriangleE')[uid = 2] as foo"); + final String query = """ + match {type:TriangleV, as: friend1, where: (uid = 0)} + return friend1.out('TriangleE')[uid = 2] as foo + """; - final ResultSet result = database.query("sql", query.toString()); + final ResultSet result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); final Result doc = result.next(); assertThat(result.hasNext()).isFalse(); @@ -1381,14 +1384,13 @@ public void testConditionInSquareBrackets() { @Test public void testIndexedEdge() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:IndexedVertex, as: one, where: (uid = 0)}"); - query.append(".out('IndexedEdge'){type:IndexedVertex, as: two, where: (uid = 1)}"); - query.append("return one, two"); - - final ResultSet result = database.query("sql", query.toString()); + final String query = """ + match {type:IndexedVertex, as: one, where: (uid = 0)} + .out('IndexedEdge'){type:IndexedVertex, as: two, where: (uid = 1)} + return one, two + """; + final ResultSet result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); final Result doc = result.next(); assertThat(result.hasNext()).isFalse(); @@ -1397,13 +1399,13 @@ public void testIndexedEdge() { @Test public void testIndexedEdgeArrows() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:IndexedVertex, as: one, where: (uid = 0)}"); - query.append("-IndexedEdge->{type:IndexedVertex, as: two, where: (uid = 1)}"); - query.append("return one, two"); + final String query = """ + match {type:IndexedVertex, as: one, where: (uid = 0)} + -IndexedEdge->{type:IndexedVertex, as: two, where: (uid = 1)} + return one, two + """; - final ResultSet result = database.query("sql", query.toString()); + final ResultSet result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); final Result doc = result.next(); assertThat(result.hasNext()).isFalse(); @@ -1412,12 +1414,11 @@ public void testIndexedEdgeArrows() { @Test public void testJson() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:IndexedVertex, as: one, where: (uid = 0)} "); - query.append("return {'name':'foo', 'uuid':one.uid}"); + final String query = """ + match {type:IndexedVertex, as: one, where: (uid = 0)} + return {'name':'foo', 'uuid':one.uid}"""; - final ResultSet result = database.query("sql", query.toString()); + final ResultSet result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); final Result doc = result.next(); assertThat(result.hasNext()).isFalse(); @@ -1430,12 +1431,12 @@ public void testJson() { @Test public void testJson2() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:IndexedVertex, as: one, where: (uid = 0)} "); - query.append("return {'name':'foo', 'sub': {'uuid':one.uid}}"); + final String query = """ + match {type:IndexedVertex, as: one, where: (uid = 0)} + return {'name':'foo', 'sub': {'uuid':one.uid}} + """; - final ResultSet result = database.query("sql", query.toString()); + final ResultSet result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); final Result doc = result.next(); assertThat(result.hasNext()).isFalse(); @@ -1447,12 +1448,12 @@ public void testJson2() { @Test public void testJson3() { - final StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:IndexedVertex, as: one, where: (uid = 0)} "); - query.append("return {'name':'foo', 'sub': [{'uuid':one.uid}]}"); + final String query = """ + match {type:IndexedVertex, as: one, where: (uid = 0)} + return {'name':'foo', 'sub': [{'uuid':one.uid}]} + """; - final ResultSet result = database.query("sql", query.toString()); + final ResultSet result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); final Result doc = result.next(); assertThat(result.hasNext()).isFalse(); @@ -1465,42 +1466,41 @@ public void testJson3() { @Test public void testUnique() { - StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:DiamondV, as: one, where: (uid = 0)}.out('DiamondE').out('DiamondE'){as: two} "); - query.append("return DISTINCT one, two"); + String query = """ + match {type:DiamondV, as: one, where: (uid = 0)} + .out('DiamondE').out('DiamondE'){as: two} + return DISTINCT one, two + """; - ResultSet result = database.query("sql", query.toString()); + ResultSet result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); Result doc = result.next(); assertThat(result.hasNext()).isFalse(); - query = new StringBuilder(); - query.append("match "); - query.append("{type:DiamondV, as: one, where: (uid = 0)}.out('DiamondE').out('DiamondE'){as: two} "); - query.append("return DISTINCT one.uid, two.uid"); + query = """ + match {type:DiamondV, as: one, where: (uid = 0)} + .out('DiamondE').out('DiamondE'){as: two} + return DISTINCT one.uid, two.uid + """; result.close(); - result = database.query("sql", query.toString()); + result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); doc = result.next(); assertThat(result.hasNext()).isFalse(); result.close(); - // Document doc = result.get(0); - // assertEquals("foo", doc.set("name"); - // assertEquals(0, doc.set("sub[0].uuid"); } @Test public void testNotUnique() { - StringBuilder query = new StringBuilder(); - query.append("match "); - query.append("{type:DiamondV, as: one, where: (uid = 0)}.out('DiamondE').out('DiamondE'){as: two} "); - query.append("return one, two"); + String query = """ + match {type:DiamondV, as: one, where: (uid = 0)}.out('DiamondE').out('DiamondE'){as: two} + return one, two + """; - ResultSet result = database.query("sql", query.toString()); + ResultSet result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); Result doc = result.next(); @@ -1509,21 +1509,18 @@ public void testNotUnique() { assertThat(result.hasNext()).isFalse(); result.close(); - query = new StringBuilder(); - query.append("match "); - query.append("{type:DiamondV, as: one, where: (uid = 0)}.out('DiamondE').out('DiamondE'){as: two} "); - query.append("return one.uid, two.uid"); + query = """ + match {type:DiamondV, as: one, where: (uid = 0)}.out('DiamondE').out('DiamondE'){as: two} + return one.uid, two.uid + """; - result = database.query("sql", query.toString()); + result = database.query("sql", query); assertThat(result.hasNext()).isTrue(); doc = result.next(); assertThat(result.hasNext()).isTrue(); doc = result.next(); assertThat(result.hasNext()).isFalse(); result.close(); - // Document doc = result.get(0); - // assertEquals("foo", doc.set("name"); - // assertEquals(0, doc.set("sub[0].uuid"); } @Test @@ -1550,15 +1547,16 @@ public void testManagedElements() { } private ResultSet getManagedElements(final String managerName) { - final StringBuilder query = new StringBuilder(); - query.append(" match {type:Employee, as:boss, where: (name = '" + managerName + "')}"); - query.append(" -ManagerOf->{}<-ParentDepartment-{"); - query.append(" while: ($depth = 0 or in('ManagerOf').size() = 0),"); - query.append(" where: ($depth = 0 or in('ManagerOf').size() = 0)"); - query.append(" }<-WorksAt-{as: managed}"); - query.append(" return distinct $elements"); + final String query = """ + match {type:Employee, as:boss, where: (name = '%s')} + -ManagerOf->{}<-ParentDepartment-{ + while: ($depth = 0 or in('ManagerOf').size() = 0), + where: ($depth = 0 or in('ManagerOf').size() = 0) + }<-WorksAt-{as: managed} + return distinct $elements + """.formatted(managerName); - return database.query("sql", query.toString()); + return database.query("sql", query); } @Test @@ -1622,11 +1620,13 @@ public void testOptional2() { @Test public void testOptional3() { - final ResultSet qResult = database.query("sql", "select friend.name as name, b from (" - + "match {type:Person, as:a, where:(name = 'n1' and 1 + 1 = 2)}.out('Friend'){as:friend, where:(name = 'n2' and 1 + 1 = 2)}," - + "{as:a}.out(){as:b, where:(nonExisting = 12), optional:true}," + "{as:friend}.out(){as:b, optional:true}" - + " return friend, b)"); - + final ResultSet qResult = database.query("sql", """ + select friend.name as name, b from ( + match {type:Person, as:a, where:(name = 'n1' and 1 + 1 = 2)}.out('Friend'){as:friend, where:(name = 'n2' and 1 + 1 = 2)}, + {as:a}.out(){as:b, where:(nonExisting = 12), optional:true}, + {as:friend}.out(){as:b, optional:true} + return friend, b) + """); assertThat(qResult.hasNext()).isTrue(); final Result doc = qResult.next(); assertThat(doc.getProperty("name")).isEqualTo("n2"); @@ -1841,7 +1841,7 @@ public void testUnwind() { for (int i = 0; i < 4; i++) { assertThat(result.hasNext()).isTrue(); final Result item = result.next(); - sum += item.getProperty("num"); + sum += item.getProperty("num"); } assertThat(result.hasNext()).isFalse(); @@ -1960,20 +1960,23 @@ public void testPathAlias() { final List thePath = (List) path; final String bname = item.getProperty("bname"); - if (bname.equals("aaa")) { - assertThat(thePath.size()).isEqualTo(0); - } else if (bname.equals("aaa")) { + switch (bname) { + case "aaa" -> assertThat(thePath.size()).isEqualTo(0); + case "bbb" -> { assertThat(thePath.size()).isEqualTo(1); - assertThat(((Document) thePath.get(0).getRecord()).getString("name")).isEqualTo("bbb"); - } else if (bname.equals("ccc")) { + assertThat( thePath.get(0).getRecord().asDocument().getString("name")).isEqualTo("bbb"); + } + case "ccc" -> { assertThat(thePath.size()).isEqualTo(2); - assertThat(((Document) thePath.get(0).getRecord()).getString("name")).isEqualTo("bbb"); - assertThat(((Document) thePath.get(1).getRecord()).getString("name")).isEqualTo("ccc"); - } else if (bname.equals("ddd")) { + assertThat(thePath.get(0).getRecord().asDocument().getString("name")).isEqualTo("bbb"); + assertThat(thePath.get(1).getRecord().asDocument().getString("name")).isEqualTo("ccc"); + } + case "ddd" -> { assertThat(thePath.size()).isEqualTo(3); - assertThat(((Document) thePath.get(0).getRecord()).getString("name")).isEqualTo("bbb"); - assertThat(((Document) thePath.get(1).getRecord()).getString("name")).isEqualTo("ccc"); - assertThat(((Document) thePath.get(2).getRecord()).getString("name")).isEqualTo("ddd"); + assertThat(thePath.get(0).getRecord().asDocument().getString("name")).isEqualTo("bbb"); + assertThat(thePath.get(1).getRecord().asDocument().getString("name")).isEqualTo("ccc"); + assertThat(thePath.get(2).getRecord().asDocument().getString("name")).isEqualTo("ddd"); + } } } assertThat(result.hasNext()).isFalse(); @@ -2024,49 +2027,49 @@ public void testBucketTarget() { assertThat(result.hasNext()).isFalse(); - assertThat(database.getSchema().getIndexByName(clazz + "[name]").get(new String[]{"one"}).hasNext()).isTrue(); - assertThat(database.getSchema().getIndexByName(clazz + "[name]").get(new String[]{"onex"}).hasNext()).isTrue(); - assertThat(database.getSchema().getIndexByName(clazz + "[name]").get(new String[]{"two"}).hasNext()).isTrue(); - assertThat(database.getSchema().getIndexByName(clazz + "[name]").get(new String[]{"three"}).hasNext()).isTrue(); + assertThat(database.getSchema().getIndexByName(clazz + "[name]").get(new String[] { "one" }).hasNext()).isTrue(); + assertThat(database.getSchema().getIndexByName(clazz + "[name]").get(new String[] { "onex" }).hasNext()).isTrue(); + assertThat(database.getSchema().getIndexByName(clazz + "[name]").get(new String[] { "two" }).hasNext()).isTrue(); + assertThat(database.getSchema().getIndexByName(clazz + "[name]").get(new String[] { "three" }).hasNext()).isTrue(); //-------------------------------------------------------------------------------------------------------- // CHECK THE SUB-INDEX EXISTS assertThat(Set.of(((TypeIndex) database.getSchema().getIndexByName(clazz + "[name]")).getIndexesOnBuckets()).stream() - .map((r) -> r.getAssociatedBucketId()).collect(Collectors.toSet()) - .contains(database.getSchema().getBucketByName(clazz + "_one").getFileId())).isTrue(); + .map(Index::getAssociatedBucketId).collect(Collectors.toSet()) + .contains(database.getSchema().getBucketByName(clazz + "_one").getFileId())).isTrue(); database.command("SQL", "ALTER TYPE " + clazz + " BUCKET -" + clazz + "_one").close(); // CHECK THE SUB-INDEX HAS BEN REMOVED assertThat(Set.of(((TypeIndex) database.getSchema().getIndexByName(clazz + "[name]")).getIndexesOnBuckets()).stream() - .map((r) -> r.getAssociatedBucketId()).collect(Collectors.toSet()) - .contains(database.getSchema().getBucketByName(clazz + "_one").getFileId())).isFalse(); + .map(Index::getAssociatedBucketId).collect(Collectors.toSet()) + .contains(database.getSchema().getBucketByName(clazz + "_one").getFileId())).isFalse(); //-------------------------------------------------------------------------------------------------------- // CHECK THE SUB-INDEX EXISTS assertThat(Set.of(((TypeIndex) database.getSchema().getIndexByName(clazz + "[name]")).getIndexesOnBuckets()).stream() - .map((r) -> r.getAssociatedBucketId()).collect(Collectors.toSet()) - .contains(database.getSchema().getBucketByName(clazz + "_two").getFileId())).isTrue(); + .map(Index::getAssociatedBucketId).collect(Collectors.toSet()) + .contains(database.getSchema().getBucketByName(clazz + "_two").getFileId())).isTrue(); database.command("SQL", "ALTER TYPE " + clazz + " BUCKET -" + clazz + "_two").close(); // CHECK THE SUB-INDEX HAS BEN REMOVED assertThat(Set.of(((TypeIndex) database.getSchema().getIndexByName(clazz + "[name]")).getIndexesOnBuckets()).stream() - .map((r) -> r.getAssociatedBucketId()).collect(Collectors.toSet()) - .contains(database.getSchema().getBucketByName(clazz + "_two").getFileId())).isFalse(); + .map(Index::getAssociatedBucketId).collect(Collectors.toSet()) + .contains(database.getSchema().getBucketByName(clazz + "_two").getFileId())).isFalse(); //-------------------------------------------------------------------------------------------------------- // CHECK THE SUB-INDEX EXISTS assertThat(Set.of(((TypeIndex) database.getSchema().getIndexByName(clazz + "[name]")).getIndexesOnBuckets()).stream() - .map((r) -> r.getAssociatedBucketId()).collect(Collectors.toSet()) - .contains(database.getSchema().getBucketByName(clazz + "_three").getFileId())).isTrue(); + .map(Index::getAssociatedBucketId).collect(Collectors.toSet()) + .contains(database.getSchema().getBucketByName(clazz + "_three").getFileId())).isTrue(); database.command("SQL", "ALTER TYPE " + clazz + " BUCKET -" + clazz + "_three").close(); // CHECK THE SUB-INDEX HAS BEN REMOVED assertThat(Set.of(((TypeIndex) database.getSchema().getIndexByName(clazz + "[name]")).getIndexesOnBuckets()).stream() - .map((r) -> r.getAssociatedBucketId()).collect(Collectors.toSet()) - .contains(database.getSchema().getBucketByName(clazz + "_three").getFileId())).isFalse(); + .map(Index::getAssociatedBucketId).collect(Collectors.toSet()) + .contains(database.getSchema().getBucketByName(clazz + "_three").getFileId())).isFalse(); result.close(); } @@ -2218,15 +2221,16 @@ public void testPathTraversal() { } private ResultSet getManagedPathElements(final String managerName) { - final StringBuilder query = new StringBuilder(); - query.append(" match {type:Employee, as:boss, where: (name = '" + managerName + "')}"); - query.append(" -ManagerOf->{}<-ParentDepartment-{"); - query.append(" while: ($depth = 0 or in('ManagerOf').size() = 0),"); - query.append(" where: ($depth = 0 or in('ManagerOf').size() = 0)"); - query.append(" }<-WorksAt-{as: managed}"); - query.append(" return distinct $pathElements"); + final String query = """ + match {type:Employee, as:boss, where: (name = '%s')} + -ManagerOf->{}<-ParentDepartment-{ + while: ($depth = 0 or in('ManagerOf').size() = 0), + where: ($depth = 0 or in('ManagerOf').size() = 0) + }<-WorksAt-{as: managed} + return distinct $pathElements + """.formatted(managerName); - return database.query("sql", query.toString()); + return database.query("sql", query); } @Test @@ -2244,8 +2248,7 @@ public void testQuotedClassName() { @Test public void testMatchInSubQuery() { - try (final ResultSet rs = database.query("SQL", - "SELECT $a LET $a=(MATCH{type:Person,as:Person_0}RETURN expand(Person_0))")) { + try (final ResultSet rs = database.query("SQL", "SELECT $a LET $a=(MATCH{type:Person,as:Person_0}RETURN expand(Person_0))")) { assertThat(rs.stream().count()).isEqualTo(1L); } } diff --git a/engine/src/test/java/com/arcadedb/query/sql/executor/WhileBlockExecutionTest.java b/engine/src/test/java/com/arcadedb/query/sql/executor/WhileBlockExecutionTest.java index b9cc28c722..8c0dc54b2f 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/executor/WhileBlockExecutionTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/executor/WhileBlockExecutionTest.java @@ -38,21 +38,21 @@ public void testPlain() { database.getSchema().createDocumentType(className); - String script = ""; - script += "LET $i = 0;"; - script += "WHILE ($i < 3){\n"; - script += " insert into " + className + " set value = $i;\n"; - script += " LET $i = $i + 1;"; - script += "}"; - script += "SELECT FROM " + className + ";"; - + String script = """ + LET $i = 0; + WHILE ($i < 3){ + insert into %s set value = $i; + LET $i = $i + 1; + } + SELECT FROM %s; + """.formatted(className, className); final ResultSet results = database.command("sqlscript", script); int tot = 0; int sum = 0; while (results.hasNext()) { final Result item = results.next(); - sum += item.getProperty("value"); + sum += item.getProperty("value"); tot++; } assertThat(tot).isEqualTo(3); @@ -66,16 +66,16 @@ public void testReturn() { database.getSchema().createDocumentType(className); - String script = ""; - script += "LET $i = 0;"; - script += "WHILE ($i < 3){\n"; - script += " insert into " + className + " set value = $i;\n"; - script += " IF ($i = 1) {"; - script += " RETURN;"; - script += " }"; - script += " LET $i = $i + 1;"; - script += "}"; - + String script = """ + LET $i = 0; + WHILE ($i < 3){ + insert into %s set value = $i; + IF ($i = 1) { + RETURN; + } + LET $i = $i + 1; + } + """.formatted(className); ResultSet results = database.command("sqlscript", script); results.close(); results = database.query("sql", "SELECT FROM " + className); @@ -84,7 +84,7 @@ public void testReturn() { int sum = 0; while (results.hasNext()) { final Result item = results.next(); - sum += item.getProperty("value"); + sum += item.getProperty("value"); tot++; } assertThat(tot).isEqualTo(2); diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/coll/SQLFunctionDifferenceTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/coll/SQLFunctionDifferenceTest.java similarity index 94% rename from engine/src/test/java/com/arcadedb/query/sql/functions/coll/SQLFunctionDifferenceTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/coll/SQLFunctionDifferenceTest.java index d4625a4ee2..d83e2fb072 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/coll/SQLFunctionDifferenceTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/coll/SQLFunctionDifferenceTest.java @@ -16,10 +16,9 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.coll; +package com.arcadedb.query.sql.function.coll; import com.arcadedb.query.sql.executor.BasicCommandContext; -import com.arcadedb.query.sql.function.coll.SQLFunctionDifference; import org.junit.jupiter.api.Test; import java.util.*; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/coll/SQLFunctionIntersectTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/coll/SQLFunctionIntersectTest.java similarity index 94% rename from engine/src/test/java/com/arcadedb/query/sql/functions/coll/SQLFunctionIntersectTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/coll/SQLFunctionIntersectTest.java index f1a3de8327..12ef5140de 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/coll/SQLFunctionIntersectTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/coll/SQLFunctionIntersectTest.java @@ -16,10 +16,9 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.coll; +package com.arcadedb.query.sql.function.coll; import com.arcadedb.query.sql.executor.BasicCommandContext; -import com.arcadedb.query.sql.function.coll.SQLFunctionIntersect; import org.junit.jupiter.api.Test; import java.util.*; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/coll/SQLFunctionSymmetricDifferenceTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/coll/SQLFunctionSymmetricDifferenceTest.java similarity index 95% rename from engine/src/test/java/com/arcadedb/query/sql/functions/coll/SQLFunctionSymmetricDifferenceTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/coll/SQLFunctionSymmetricDifferenceTest.java index 5301f30451..ff528c2553 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/coll/SQLFunctionSymmetricDifferenceTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/coll/SQLFunctionSymmetricDifferenceTest.java @@ -16,10 +16,9 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.coll; +package com.arcadedb.query.sql.function.coll; import com.arcadedb.query.sql.executor.BasicCommandContext; -import com.arcadedb.query.sql.function.coll.SQLFunctionSymmetricDifference; import org.junit.jupiter.api.Test; import java.util.*; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/geo/SQLGeoFunctionsTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/geo/SQLGeoFunctionsTest.java similarity index 99% rename from engine/src/test/java/com/arcadedb/query/sql/functions/geo/SQLGeoFunctionsTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/geo/SQLGeoFunctionsTest.java index 265d54b109..00c6ac0555 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/geo/SQLGeoFunctionsTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/geo/SQLGeoFunctionsTest.java @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.geo; +package com.arcadedb.query.sql.function.geo; import com.arcadedb.TestHelper; import com.arcadedb.database.Document; @@ -27,7 +27,6 @@ import com.arcadedb.schema.Schema; import com.arcadedb.schema.Type; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.locationtech.spatial4j.io.GeohashUtils; import org.locationtech.spatial4j.shape.Circle; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/graph/SQLFunctionAdjacencyTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/graph/SQLFunctionAdjacencyTest.java similarity index 93% rename from engine/src/test/java/com/arcadedb/query/sql/functions/graph/SQLFunctionAdjacencyTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/graph/SQLFunctionAdjacencyTest.java index 21e91e4cc6..dfa99d1807 100755 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/graph/SQLFunctionAdjacencyTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/graph/SQLFunctionAdjacencyTest.java @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.graph; +package com.arcadedb.query.sql.function.graph; import com.arcadedb.TestHelper; import com.arcadedb.database.Database; @@ -27,17 +27,7 @@ import com.arcadedb.graph.MutableVertex; import com.arcadedb.graph.Vertex; import com.arcadedb.query.sql.executor.BasicCommandContext; -import com.arcadedb.query.sql.function.graph.SQLFunctionBoth; -import com.arcadedb.query.sql.function.graph.SQLFunctionBothE; -import com.arcadedb.query.sql.function.graph.SQLFunctionBothV; -import com.arcadedb.query.sql.function.graph.SQLFunctionIn; -import com.arcadedb.query.sql.function.graph.SQLFunctionInE; -import com.arcadedb.query.sql.function.graph.SQLFunctionInV; -import com.arcadedb.query.sql.function.graph.SQLFunctionOut; -import com.arcadedb.query.sql.function.graph.SQLFunctionOutE; -import com.arcadedb.query.sql.function.graph.SQLFunctionOutV; - -import org.assertj.core.api.Assertions; + import org.junit.jupiter.api.Test; import java.util.*; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/graph/SQLFunctionAstarTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/graph/SQLFunctionAstarTest.java similarity index 99% rename from engine/src/test/java/com/arcadedb/query/sql/functions/graph/SQLFunctionAstarTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/graph/SQLFunctionAstarTest.java index 5df39e18f6..7a0460f4fc 100755 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/graph/SQLFunctionAstarTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/graph/SQLFunctionAstarTest.java @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.graph; +package com.arcadedb.query.sql.function.graph; import com.arcadedb.TestHelper; import com.arcadedb.database.Database; @@ -26,8 +26,6 @@ import com.arcadedb.query.sql.executor.BasicCommandContext; import com.arcadedb.query.sql.executor.Result; import com.arcadedb.query.sql.executor.ResultSet; -import com.arcadedb.query.sql.function.graph.SQLFunctionAstar; -import com.arcadedb.query.sql.function.graph.SQLHeuristicFormula; import org.junit.jupiter.api.Test; import java.util.*; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/graph/SQLFunctionDijkstraTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/graph/SQLFunctionDijkstraTest.java similarity index 96% rename from engine/src/test/java/com/arcadedb/query/sql/functions/graph/SQLFunctionDijkstraTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/graph/SQLFunctionDijkstraTest.java index 3f866608d8..bd034c6356 100755 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/graph/SQLFunctionDijkstraTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/graph/SQLFunctionDijkstraTest.java @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.graph; +package com.arcadedb.query.sql.function.graph; import com.arcadedb.TestHelper; import com.arcadedb.database.Database; @@ -24,7 +24,6 @@ import com.arcadedb.graph.MutableVertex; import com.arcadedb.graph.Vertex; import com.arcadedb.query.sql.executor.BasicCommandContext; -import com.arcadedb.query.sql.function.graph.SQLFunctionDijkstra; import org.junit.jupiter.api.Test; import java.util.*; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/graph/SQLFunctionShortestPathTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/graph/SQLFunctionShortestPathTest.java similarity index 98% rename from engine/src/test/java/com/arcadedb/query/sql/functions/graph/SQLFunctionShortestPathTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/graph/SQLFunctionShortestPathTest.java index 0b0d63e01b..1d09c813a4 100755 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/graph/SQLFunctionShortestPathTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/graph/SQLFunctionShortestPathTest.java @@ -16,14 +16,13 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.graph; +package com.arcadedb.query.sql.function.graph; import com.arcadedb.TestHelper; import com.arcadedb.database.Database; import com.arcadedb.database.RID; import com.arcadedb.graph.MutableVertex; import com.arcadedb.query.sql.executor.BasicCommandContext; -import com.arcadedb.query.sql.function.graph.SQLFunctionShortestPath; import org.junit.jupiter.api.Test; import java.util.*; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionAbsoluteValueTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionAbsoluteValueTest.java similarity index 98% rename from engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionAbsoluteValueTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionAbsoluteValueTest.java index c57d6ddd49..0653cd9a38 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionAbsoluteValueTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionAbsoluteValueTest.java @@ -16,11 +16,10 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.math; +package com.arcadedb.query.sql.function.math; import com.arcadedb.TestHelper; import com.arcadedb.query.sql.executor.ResultSet; -import com.arcadedb.query.sql.function.math.SQLFunctionAbsoluteValue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionModeTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionModeTest.java similarity index 95% rename from engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionModeTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionModeTest.java index 7408c22f8c..4d540a47ca 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionModeTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionModeTest.java @@ -16,9 +16,8 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.math; +package com.arcadedb.query.sql.function.math; -import com.arcadedb.query.sql.function.math.SQLFunctionMode; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionPercentileTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionPercentileTest.java similarity index 96% rename from engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionPercentileTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionPercentileTest.java index d883a02dbe..4f26c7305c 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionPercentileTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionPercentileTest.java @@ -16,9 +16,8 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.math; +package com.arcadedb.query.sql.function.math; -import com.arcadedb.query.sql.function.math.SQLFunctionPercentile; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionRandomIntTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionRandomIntTest.java similarity index 95% rename from engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionRandomIntTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionRandomIntTest.java index 10f734f0a5..571ec64a2f 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionRandomIntTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionRandomIntTest.java @@ -16,12 +16,11 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.math; +package com.arcadedb.query.sql.function.math; import com.arcadedb.TestHelper; import com.arcadedb.query.sql.executor.Result; import com.arcadedb.query.sql.executor.ResultSet; -import com.arcadedb.query.sql.function.math.SQLFunctionRandomInt; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionSquareRootTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionSquareRootTest.java similarity index 98% rename from engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionSquareRootTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionSquareRootTest.java index 223c34b75d..64c2ccf2b2 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionSquareRootTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionSquareRootTest.java @@ -16,11 +16,10 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.math; +package com.arcadedb.query.sql.function.math; import com.arcadedb.TestHelper; import com.arcadedb.query.sql.executor.ResultSet; -import com.arcadedb.query.sql.function.math.SQLFunctionSquareRoot; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionVarianceTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionVarianceTest.java similarity index 95% rename from engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionVarianceTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionVarianceTest.java index f3f268dcf8..5cb1e1e717 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/math/SQLFunctionVarianceTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/math/SQLFunctionVarianceTest.java @@ -16,9 +16,8 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.math; +package com.arcadedb.query.sql.function.math; -import com.arcadedb.query.sql.function.math.SQLFunctionVariance; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/misc/FunctionTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/misc/FunctionTest.java similarity index 97% rename from engine/src/test/java/com/arcadedb/query/sql/functions/misc/FunctionTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/misc/FunctionTest.java index 433df8c9fb..19fd6681bb 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/misc/FunctionTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/misc/FunctionTest.java @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.misc; +package com.arcadedb.query.sql.function.misc; import com.arcadedb.TestHelper; import com.arcadedb.database.MutableDocument; @@ -24,13 +24,11 @@ import com.arcadedb.query.sql.executor.Result; import com.arcadedb.query.sql.executor.ResultSet; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import java.util.*; import java.util.concurrent.atomic.*; -import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.assertThat; public class FunctionTest extends TestHelper { diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionBoolAndTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionBoolAndTest.java similarity index 98% rename from engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionBoolAndTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionBoolAndTest.java index 93b9db944b..ebc19c7182 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionBoolAndTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionBoolAndTest.java @@ -16,12 +16,11 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.misc; +package com.arcadedb.query.sql.function.misc; import com.arcadedb.TestHelper; import com.arcadedb.query.sql.executor.ResultSet; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionBoolOrTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionBoolOrTest.java similarity index 98% rename from engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionBoolOrTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionBoolOrTest.java index c3b39160e6..0493ee53ed 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionBoolOrTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionBoolOrTest.java @@ -16,12 +16,11 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.misc; +package com.arcadedb.query.sql.function.misc; import com.arcadedb.TestHelper; import com.arcadedb.query.sql.executor.ResultSet; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.*; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionCoalesceTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionCoalesceTest.java similarity index 95% rename from engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionCoalesceTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionCoalesceTest.java index 8ca3720692..3ab17cf00b 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionCoalesceTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionCoalesceTest.java @@ -16,12 +16,11 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.misc; +package com.arcadedb.query.sql.function.misc; import com.arcadedb.TestHelper; import com.arcadedb.query.sql.executor.ResultSet; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import java.util.*; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionConvertTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionConvertTest.java similarity index 99% rename from engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionConvertTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionConvertTest.java index 52b5878060..9907705664 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionConvertTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionConvertTest.java @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.misc; +package com.arcadedb.query.sql.function.misc; import com.arcadedb.GlobalConfiguration; import com.arcadedb.TestHelper; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionEncodeDecodeTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionEncodeDecodeTest.java similarity index 92% rename from engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionEncodeDecodeTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionEncodeDecodeTest.java index 23b4ab902d..85ec81c340 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionEncodeDecodeTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionEncodeDecodeTest.java @@ -16,13 +16,11 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.misc; +package com.arcadedb.query.sql.function.misc; import com.arcadedb.TestHelper; import com.arcadedb.query.sql.executor.Result; import com.arcadedb.query.sql.executor.ResultSet; -import com.arcadedb.query.sql.function.misc.SQLFunctionDecode; -import com.arcadedb.query.sql.function.misc.SQLFunctionEncode; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionUUIDTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionUUIDTest.java similarity index 94% rename from engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionUUIDTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionUUIDTest.java index 156fa40f78..805fa03d55 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/misc/SQLFunctionUUIDTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/misc/SQLFunctionUUIDTest.java @@ -16,12 +16,11 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.misc; +package com.arcadedb.query.sql.function.misc; import com.arcadedb.TestHelper; import com.arcadedb.query.sql.executor.Result; import com.arcadedb.query.sql.executor.ResultSet; -import com.arcadedb.query.sql.function.misc.SQLFunctionUUID; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/sql/CustomSQLFunctionsTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/sql/CustomSQLFunctionsTest.java similarity index 97% rename from engine/src/test/java/com/arcadedb/query/sql/functions/sql/CustomSQLFunctionsTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/sql/CustomSQLFunctionsTest.java index b009ab97eb..b635803b0d 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/sql/CustomSQLFunctionsTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/sql/CustomSQLFunctionsTest.java @@ -16,12 +16,11 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.sql; +package com.arcadedb.query.sql.function.sql; import com.arcadedb.TestHelper; import com.arcadedb.exception.CommandParsingException; import com.arcadedb.query.sql.executor.ResultSet; -import org.assertj.core.data.Offset; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/sql/SQLFunctionsTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/sql/SQLFunctionsTest.java similarity index 99% rename from engine/src/test/java/com/arcadedb/query/sql/functions/sql/SQLFunctionsTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/sql/SQLFunctionsTest.java index e7223ce0f9..dda216459f 100755 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/sql/SQLFunctionsTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/sql/SQLFunctionsTest.java @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.sql; +package com.arcadedb.query.sql.function.sql; import com.arcadedb.database.Database; import com.arcadedb.database.DatabaseFactory; @@ -36,7 +36,6 @@ import com.arcadedb.schema.Type; import com.arcadedb.utility.CollectionUtils; import com.arcadedb.utility.FileUtils; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -49,7 +48,6 @@ import java.util.stream.Collectors; import static com.arcadedb.TestHelper.checkActiveDatabases; -import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; diff --git a/engine/src/test/java/com/arcadedb/query/sql/function/text/SQLFunctionConcatTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/text/SQLFunctionConcatTest.java new file mode 100644 index 0000000000..89edb14d7b --- /dev/null +++ b/engine/src/test/java/com/arcadedb/query/sql/function/text/SQLFunctionConcatTest.java @@ -0,0 +1,64 @@ +package com.arcadedb.query.sql.function.text; + +import com.arcadedb.TestHelper; +import com.arcadedb.database.Database; +import com.arcadedb.query.sql.executor.ResultSet; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class SQLFunctionConcatTest { + private SQLFunctionConcat function; + + @BeforeEach + public void setup() { + function = new SQLFunctionConcat(); + } + + @Test + public void testConcatSingleField() { + function.execute(null, null, null, new Object[] { "Hello" }, null); + function.execute(null, null, null, new Object[] { "World" }, null); + Object result = function.getResult(); + assertThat(result).isEqualTo("HelloWorld"); + } + + @Test + public void testConcatWithDelimiter() { + function.execute(null, null, null, new Object[] { "Hello", " " }, null); + function.execute(null, null, null, new Object[] { "World", " " }, null); + Object result = function.getResult(); + assertThat(result).isEqualTo("Hello World"); + } + + @Test + public void testConcatEmpty() { + Object result = function.getResult(); + assertThat(result).isNull(); + } + + @Test + public void testConcatWithNullValues() { + function.execute(null, null, null, new Object[] { null, " " }, null); + function.execute(null, null, null, new Object[] { "World", " " }, null); + Object result = function.getResult(); + assertThat(result).isEqualTo("null World"); + } + + @Test + public void testQuery() throws Exception { + TestHelper.executeInNewDatabase("SQLFunctionConcat", (db) -> { + setUpDatabase(db); + ResultSet result = db.query("sql", "select concat(name, ' ') as concat from Person"); + assertThat(result.hasNext()).isTrue(); + assertThat(result.next().getProperty("concat")).isEqualTo("Alan Brian"); + }); + } + + private void setUpDatabase(Database db) { + db.command("sql", "create document type Person"); + db.command("sql", "insert into Person set name = 'Alan'"); + db.command("sql", "insert into Person set name = 'Brian'"); + } +} diff --git a/engine/src/test/java/com/arcadedb/query/sql/functions/text/SQLFunctionStrcmpciTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/text/SQLFunctionStrcmpciTest.java similarity index 93% rename from engine/src/test/java/com/arcadedb/query/sql/functions/text/SQLFunctionStrcmpciTest.java rename to engine/src/test/java/com/arcadedb/query/sql/function/text/SQLFunctionStrcmpciTest.java index 094bddc948..e04d0a5f3d 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/functions/text/SQLFunctionStrcmpciTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/function/text/SQLFunctionStrcmpciTest.java @@ -16,17 +16,14 @@ * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) * SPDX-License-Identifier: Apache-2.0 */ -package com.arcadedb.query.sql.functions.text; +package com.arcadedb.query.sql.function.text; import com.arcadedb.TestHelper; import com.arcadedb.query.sql.executor.ResultSet; -import com.arcadedb.query.sql.function.text.SQLFunctionStrcmpci; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.assertThat; /** diff --git a/engine/src/test/java/com/arcadedb/query/sql/function/time/SQLFunctionDurationTest.java b/engine/src/test/java/com/arcadedb/query/sql/function/time/SQLFunctionDurationTest.java new file mode 100644 index 0000000000..ab3b08fb4b --- /dev/null +++ b/engine/src/test/java/com/arcadedb/query/sql/function/time/SQLFunctionDurationTest.java @@ -0,0 +1,64 @@ +package com.arcadedb.query.sql.function.time; + +import com.arcadedb.TestHelper; +import com.arcadedb.exception.SerializationException; +import com.arcadedb.query.sql.executor.BasicCommandContext; +import com.arcadedb.query.sql.executor.CommandContext; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.time.Duration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.useDefaultDateFormatsOnly; + +public class SQLFunctionDurationTest { + + private SQLFunctionDuration function; + + @BeforeEach + public void setup() { + function = new SQLFunctionDuration(); + } + + @Test + public void testDurationWithValidParameters() throws Exception { + TestHelper.executeInNewDatabase((db) -> { + db.command("sql", "alter database `arcadedb.dateTimeImplementation` `java.time.LocalDateTime`"); + db.command("sql", "alter database `arcadedb.dateImplementation` `java.time.LocalDate`"); + + final BasicCommandContext context = new BasicCommandContext(); + context.setDatabase(db); + + Object result = function.execute(null, null, null, new Object[] { 5, "second" }, context); + assertThat(result).isEqualTo(Duration.ofSeconds(5)); + + result = function.execute(null, null, null, new Object[] { 2, "minute" }, null); + assertThat(result).isEqualTo(Duration.ofMinutes(2)); + }); + + } + + @Test + public void testDurationWithInvalidAmount() { + + assertThatThrownBy(() -> function.execute(null, null, null, new Object[] { "invalid", "SECONDS" }, null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("invalid"); + + } + + @Test + public void testDurationWithInvalidTimeUnit() { + assertThatThrownBy(() -> function.execute(null, null, null, new Object[] { 5, "INVALID_UNIT" }, null)) + .isInstanceOf(SerializationException.class) + .hasMessageContaining("Unsupported datetime precision 'INVALID_UNIT'"); + } + + @Test + public void testDurationWithIncorrectNumberOfParameters() { + assertThatThrownBy(() -> function.execute(null, null, null, new Object[] { 5 }, null)).isInstanceOf( + IllegalArgumentException.class).hasMessageContaining("duration() function expected 2 parameters: amount and time-unit"); + } +} diff --git a/engine/src/test/java/com/arcadedb/query/sql/method/collection/SQLMethodKeysTest.java b/engine/src/test/java/com/arcadedb/query/sql/method/collection/SQLMethodKeysTest.java index c9cfc54b4b..9cbffeb269 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/method/collection/SQLMethodKeysTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/method/collection/SQLMethodKeysTest.java @@ -43,6 +43,20 @@ public void testWithResult() { resultInternal.setProperty("surname", "Bar"); final Object result = function.execute(resultInternal, null, null, null); - assertThat(result).isEqualTo(new LinkedHashSet(Arrays.asList("name", "surname"))); + assertThat(result).isEqualTo(Set.of("name", "surname")); + } + + @Test + public void testWithCollection() { + List> collection = List.of(Map.of("key1", "value1"), Map.of("key2", "value2")); + + Object result = function.execute(collection, null, null, null); + assertThat(result).isEqualTo(List.of("key1", "key2")); + } + + @Test + public void testWithNull() { + Object result = function.execute(null, null, null, null); + assertThat(result).isNull(); } } diff --git a/engine/src/test/java/com/arcadedb/query/sql/method/misc/SQLMethodPrecisionTest.java b/engine/src/test/java/com/arcadedb/query/sql/method/misc/SQLMethodPrecisionTest.java index 7a519aa1fe..5cfb13025c 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/method/misc/SQLMethodPrecisionTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/method/misc/SQLMethodPrecisionTest.java @@ -53,21 +53,26 @@ void testRequiredArgs() { @Test void testLocalDateTime() throws Exception { - testPrecision("microsecond", () -> LocalDateTime.now()); - testPrecision("millisecond", () -> LocalDateTime.now()); + testPrecision("microsecond", LocalDateTime::now); + testPrecision("microseconds", LocalDateTime::now); + testPrecision("millisecond", LocalDateTime::now); + testPrecision("milliseconds", LocalDateTime::now); } @Test void testZonedDateTime() throws Exception { - testPrecision("microsecond", () -> ZonedDateTime.now()); - testPrecision("millisecond", () -> ZonedDateTime.now()); + testPrecision("microsecond", ZonedDateTime::now); + testPrecision("millisecond", ZonedDateTime::now); } @Test void testInstant() throws Exception { testPrecision("microsecond", () -> new NanoClock().instant()); + testPrecision("microseconds", () -> new NanoClock().instant()); testPrecision("millisecond", () -> new NanoClock().instant()); + testPrecision("milliseconds", () -> new NanoClock().instant()); testPrecision("nanosecond", () -> new NanoClock().instant()); + testPrecision("nanoseconds", () -> new NanoClock().instant()); } @Test diff --git a/integration/src/main/java/com/arcadedb/integration/exporter/ExporterSettings.java b/integration/src/main/java/com/arcadedb/integration/exporter/ExporterSettings.java index 7cc39094f3..418b085fce 100644 --- a/integration/src/main/java/com/arcadedb/integration/exporter/ExporterSettings.java +++ b/integration/src/main/java/com/arcadedb/integration/exporter/ExporterSettings.java @@ -33,9 +33,6 @@ public class ExporterSettings { public Set excludeTypes; public final Map options = new HashMap<>(); - public ExporterSettings() { - } - protected void parseParameters(final String[] args) { if (args != null) for (int i = 0; i < args.length - 1; ) diff --git a/postgresw/src/main/java/com/arcadedb/postgres/PostgresNetworkExecutor.java b/postgresw/src/main/java/com/arcadedb/postgres/PostgresNetworkExecutor.java index ede2dab7bf..8b2f117ec9 100755 --- a/postgresw/src/main/java/com/arcadedb/postgres/PostgresNetworkExecutor.java +++ b/postgresw/src/main/java/com/arcadedb/postgres/PostgresNetworkExecutor.java @@ -51,6 +51,8 @@ import java.util.*; import java.util.concurrent.*; import java.util.logging.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Postgres Reference for Protocol Messages: https://www.postgresql.org/docs/9.6/protocol-message-formats.html @@ -104,25 +106,21 @@ public PostgresNetworkExecutor(final ArcadeDBServer server, final Socket socket, public void close() { shutdown = true; - if (channel != null) - channel.close(); + if (channel != null) channel.close(); } @Override public void run() { try { - if (!readStartupMessage(true)) - return; + if (!readStartupMessage(true)) return; writeMessage("request for password", () -> channel.writeUnsignedInt(3), 'R', 8); waitForAMessage(); - if (!readMessage("password", (type, length) -> userPassword = readString(), 'p')) - return; + if (!readMessage("password", (type, length) -> userPassword = readString(), 'p')) return; - if (!openDatabase()) - return; + if (!openDatabase()) return; writeMessage("authentication ok", () -> channel.writeUnsignedInt(0), 'R', 8); @@ -150,45 +148,20 @@ public void run() { consecutiveErrors = 0; switch (type) { - case 'P': - parseCommand(); - break; - - case 'B': - bindCommand(); - break; - - case 'E': - executeCommand(); - break; - - case 'Q': - queryCommand(); - break; - - case 'S': - syncCommand(); - break; - - case 'D': - describeCommand(); - break; - - case 'C': - closeCommand(); - break; - - case 'H': - flushCommand(); - break; - - case 'X': + case 'P' -> parseCommand(); + case 'B' -> bindCommand(); + case 'E' -> executeCommand(); + case 'Q' -> queryCommand(); + case 'S' -> syncCommand(); + case 'D' -> describeCommand(); + case 'C' -> closeCommand(); + case 'H' -> flushCommand(); + case 'X' -> { // TERMINATE shutdown = true; return; - - default: - throw new PostgresProtocolException("Message '" + type + "' not managed"); + } + default -> throw new PostgresProtocolException("Message '" + type + "' not managed"); } }, 'P', 'B', 'E', 'Q', 'S', 'D', 'C', 'H', 'X'); @@ -219,23 +192,20 @@ public void run() { } private void syncCommand() { - if (DEBUG) - LogManager.instance().log(this, Level.INFO, "PSQL: sync (thread=%s)", Thread.currentThread().getId()); + if (DEBUG) LogManager.instance().log(this, Level.INFO, "PSQL: sync (thread=%s)", Thread.currentThread().getId()); if (errorInTransaction) { // DISCARDED PREVIOUS MESSAGES TILL THIS POINT database.rollback(); errorInTransaction = false; } else if (!explicitTransactionStarted) { - if (database.isTransactionActive()) - database.commit(); + if (database.isTransactionActive()) database.commit(); } writeReadyForQueryMessage(); } private void flushCommand() { - if (DEBUG) - LogManager.instance().log(this, Level.INFO, "PSQL: flush (thread=%s)", Thread.currentThread().getId()); + if (DEBUG) LogManager.instance().log(this, Level.INFO, "PSQL: flush (thread=%s)", Thread.currentThread().getId()); writeReadyForQueryMessage(); } @@ -243,15 +213,13 @@ private void closeCommand() throws IOException { final byte closeType = channel.readByte(); final String prepStatementOrPortal = readString(); - if (errorInTransaction) - return; + if (errorInTransaction) return; - if (closeType == 'P') - getPortal(prepStatementOrPortal, true); + if (closeType == 'P') getPortal(prepStatementOrPortal, true); - if (DEBUG) - LogManager.instance().log(this, Level.INFO, "PSQL: close '%s' type=%s (thread=%s)", prepStatementOrPortal, (char) closeType, - Thread.currentThread().getId()); + if (DEBUG) LogManager.instance() + .log(this, Level.INFO, "PSQL: close '%s' type=%s (thread=%s)", prepStatementOrPortal, (char) closeType, + Thread.currentThread().getId()); writeMessage("close complete", null, '3', 4); } @@ -260,13 +228,11 @@ private void describeCommand() throws IOException { final byte type = channel.readByte(); final String portalName = readString(); - if (DEBUG) - LogManager.instance() - .log(this, Level.INFO, "PSQL: describe '%s' type=%s (errorInTransaction=%s thread=%s)", portalName, (char) type, - errorInTransaction, Thread.currentThread().getId()); + if (DEBUG) LogManager.instance() + .log(this, Level.INFO, "PSQL: describe '%s' type=%s (errorInTransaction=%s thread=%s)", portalName, (char) type, + errorInTransaction, Thread.currentThread().getId()); - if (errorInTransaction) - return; + if (errorInTransaction) return; final PostgresPortal portal = getPortal(portalName, false); if (portal == null) { @@ -283,16 +249,13 @@ private void describeCommand() throws IOException { portal.cachedResultset = browseAndCacheResultSet(resultSet, 0); portal.columns = getColumns(portal.cachedResultset); writeRowDescription(portal.columns); - } else - writeNoData(); + } else writeNoData(); } else { - if (portal.columns != null) - writeRowDescription(portal.columns); + if (portal.columns != null) writeRowDescription(portal.columns); } } else if (type == 'S') { writeNoData(); - } else - throw new PostgresProtocolException("Unexpected describe type '" + type + "'"); + } else throw new PostgresProtocolException("Unexpected describe type '" + type + "'"); } private void executeCommand() { @@ -300,8 +263,7 @@ private void executeCommand() { final String portalName = readString(); final int limit = (int) channel.readUnsignedInt(); - if (errorInTransaction) - return; + if (errorInTransaction) return; final PostgresPortal portal = getPortal(portalName, true); if (portal == null) { @@ -309,13 +271,11 @@ private void executeCommand() { return; } - if (DEBUG) - LogManager.instance() - .log(this, Level.INFO, "PSQL: execute (portal=%s) (limit=%d)-> %s (thread=%s)", portalName, limit, portal, - Thread.currentThread().getId()); + if (DEBUG) LogManager.instance() + .log(this, Level.INFO, "PSQL: execute (portal=%s) (limit=%d)-> %s (thread=%s)", portalName, limit, portal, + Thread.currentThread().getId()); - if (portal.ignoreExecution) - writeNoData(); + if (portal.ignoreExecution) writeNoData(); else { if (!portal.executed) { final Object[] parameters = portal.parameterValues != null ? portal.parameterValues.toArray() : new Object[0]; @@ -329,13 +289,11 @@ private void executeCommand() { } if (portal.isExpectingResult) { - if (portal.columns == null) - portal.columns = getColumns(portal.cachedResultset); + if (portal.columns == null) portal.columns = getColumns(portal.cachedResultset); writeDataRows(portal.cachedResultset, portal.columns); writeCommandComplete(portal.query, portal.cachedResultset == null ? 0 : portal.cachedResultset.size()); - } else - writeNoData(); + } else writeNoData(); } } catch (final CommandParsingException e) { setErrorInTx(); @@ -349,11 +307,9 @@ private void executeCommand() { private void queryCommand() { try { String queryText = readString().trim(); - if (queryText.endsWith(";")) - queryText = queryText.substring(0, queryText.length() - 1); + if (queryText.endsWith(";")) queryText = queryText.substring(0, queryText.length() - 1); - if (errorInTransaction) - return; + if (errorInTransaction) return; if (queryText.isEmpty()) { emptyQueryResponse(); @@ -363,9 +319,7 @@ private void queryCommand() { if (DEBUG) LogManager.instance().log(this, Level.INFO, "PSQL: query -> %s (thread=%s)", queryText, Thread.currentThread().getId()); - final String[] query = getLanguageAndQuery(queryText); - final String language = query[0]; - queryText = query[1]; + final Query query = getLanguageAndQuery(queryText); final ResultSet resultSet; if (queryText.startsWith("SET ")) { @@ -379,10 +333,8 @@ else if (queryText.equalsIgnoreCase("BEGIN") || queryText.equalsIgnoreCase("BEGI explicitTransactionStarted = true; database.begin(); resultSet = new IteratorResultSet(Collections.emptyIterator()); - } else if (ignoreQueries.contains(queryText)) - resultSet = new IteratorResultSet(Collections.emptyIterator()); - else - resultSet = database.command(language, queryText); + } else if (ignoreQueries.contains(queryText)) resultSet = new IteratorResultSet(Collections.emptyIterator()); + else resultSet = database.command(query.language, query.query); final List cachedResultset = browseAndCacheResultSet(resultSet, 0); @@ -404,10 +356,8 @@ else if (queryText.equalsIgnoreCase("BEGIN") || queryText.equalsIgnoreCase("BEGI private void writeReadyForQueryMessage() { final byte transactionStatus; - if (explicitTransactionStarted) - transactionStatus = 'T'; - else - transactionStatus = 'I'; + if (explicitTransactionStarted) transactionStatus = 'T'; + else transactionStatus = 'I'; writeMessage("ready for query", () -> channel.writeByte(transactionStatus), 'Z', 5); } @@ -416,8 +366,7 @@ private List browseAndCacheResultSet(final ResultSet resultSet, final in final List cachedResultSet = new ArrayList<>(); while (resultSet.hasNext()) { final Result row = resultSet.next(); - if (row == null) - continue; + if (row == null) continue; cachedResultSet.add(row); @@ -435,8 +384,7 @@ private Map getColumns(final List resultSet) { if (resultSet != null) { boolean atLeastOneElement = false; for (final Result row : resultSet) { - if (row.isElement()) - atLeastOneElement = true; + if (row.isElement()) atLeastOneElement = true; final Set propertyNames = row.getPropertyNames(); for (final String p : propertyNames) { @@ -455,8 +403,7 @@ private Map getColumns(final List resultSet) { } } - if (valueType == null) - valueType = PostgresType.VARCHAR; + if (valueType == null) valueType = PostgresType.VARCHAR; columns.put(p, valueType); } @@ -475,8 +422,7 @@ private Map getColumns(final List resultSet) { } private void writeRowDescription(final Map columns) { - if (columns == null) - return; + if (columns == null) return; final ByteBuffer bufferDescription = ByteBuffer.allocate(64 * 1024).order(ByteOrder.BIG_ENDIAN); @@ -508,8 +454,7 @@ private void writeRowDescription(final Map columns) { } private void writeDataRows(final List resultSet, final Map columns) throws IOException { - if (resultSet.isEmpty()) - return; + if (resultSet.isEmpty()) return; final ByteBuffer bufferData = ByteBuffer.allocate(128 * 1024).order(ByteOrder.BIG_ENDIAN); final ByteBuffer bufferValues = ByteBuffer.allocate(128 * 1024).order(ByteOrder.BIG_ENDIAN); @@ -523,38 +468,28 @@ private void writeDataRows(final List resultSet, final Map %d row data (%s) (thread=%s)", resultSet.size(), - FileUtils.getSizeAsString(bufferData.limit()), Thread.currentThread().getId()); + if (DEBUG) LogManager.instance().log(this, Level.INFO, "PSQL:-> %d row data (%s) (thread=%s)", resultSet.size(), + FileUtils.getSizeAsString(bufferData.limit()), Thread.currentThread().getId()); } private void bindCommand() { @@ -587,9 +521,9 @@ private void bindCommand() { return; } - if (DEBUG) - LogManager.instance().log(this, Level.INFO, "PSQL: bind (portal=%s) -> %s (thread=%s)", portalName, sourcePreparedStatement, - Thread.currentThread().getId()); + if (DEBUG) LogManager.instance() + .log(this, Level.INFO, "PSQL: bind (portal=%s) -> %s (thread=%s)", portalName, sourcePreparedStatement, + Thread.currentThread().getId()); final int paramFormatCount = channel.readShort(); if (paramFormatCount > 0) { @@ -623,8 +557,7 @@ private void bindCommand() { } } - if (errorInTransaction) - return; + if (errorInTransaction) return; writeMessage("bind complete", null, '2', 4); @@ -649,13 +582,11 @@ private void parseCommand() { } } - if (DEBUG) - LogManager.instance() - .log(this, Level.INFO, "PSQL: parse (portal=%s) -> %s (params=%d) (errorInTransaction=%s thread=%s)", portalName, - portal.query, paramCount, errorInTransaction, Thread.currentThread().getId()); + if (DEBUG) LogManager.instance() + .log(this, Level.INFO, "PSQL: parse (portal=%s) -> %s (params=%d) (errorInTransaction=%s thread=%s)", portalName, + portal.query, paramCount, errorInTransaction, Thread.currentThread().getId()); - if (errorInTransaction) - return; + if (errorInTransaction) return; if (portal.query.isEmpty()) { emptyQueryResponse(); @@ -813,14 +744,12 @@ private void parseCommand() { portal.columns.put("TABLE_SCHEM", PostgresType.VARCHAR); portal.columns.put("TABLE_CATALOG", PostgresType.VARCHAR); } else { - final String[] query = getLanguageAndQuery(portal.query); - final String language = query[0]; - final String queryText = query[1]; + final Query query = getLanguageAndQuery(portal.query); - switch (language) { + switch (query.language) { case "sql": final SQLQueryEngine sqlEngine = (SQLQueryEngine) database.getQueryEngine("sql"); - portal.sqlStatement = sqlEngine.parse(queryText, (DatabaseInternal) database); + portal.sqlStatement = sqlEngine.parse(query.query, (DatabaseInternal) database); if (portal.query.equalsIgnoreCase("BEGIN") || portal.query.equalsIgnoreCase("BEGIN TRANSACTION")) { explicitTransactionStarted = true; @@ -833,7 +762,7 @@ private void parseCommand() { default: portal.executed = true; - final ResultSet resultSet = database.command(language, queryText); + final ResultSet resultSet = database.command(query.language, query.query); portal.cachedResultset = browseAndCacheResultSet(resultSet, 0); portal.columns = getColumns(portal.cachedResultset); } @@ -856,20 +785,16 @@ private void parseCommand() { private void setConfiguration(final String query) { final String q = query.substring("SET ".length()); String[] parts = q.split("="); - if (parts.length < 2) - parts = q.split(" TO "); + if (parts.length < 2) parts = q.split(" TO "); parts[0] = parts[0].trim(); parts[1] = parts[1].trim(); - if (parts[1].startsWith("'") || parts[1].startsWith("\"")) - parts[1] = parts[1].substring(1, parts[1].length() - 1); + if (parts[1].startsWith("'") || parts[1].startsWith("\"")) parts[1] = parts[1].substring(1, parts[1].length() - 1); if (parts[0].equals("datestyle")) { - if (parts[1].equals("ISO")) - database.getSchema().setDateTimeFormat(DateUtils.DATE_TIME_ISO_8601_FORMAT); - else - LogManager.instance().log(this, Level.INFO, "datestyle '%s' not supported", parts[1]); + if (parts[1].equals("ISO")) database.getSchema().setDateTimeFormat(DateUtils.DATE_TIME_ISO_8601_FORMAT); + else LogManager.instance().log(this, Level.INFO, "datestyle '%s' not supported", parts[1]); } connectionProperties.put(parts[0], parts[1]); @@ -950,10 +875,8 @@ private boolean readStartupMessage(final boolean no2ssl) { if (session.getFirst() == secret) { LogManager.instance().log(this, Level.INFO, "PSQL: Canceling session " + pid); session.getSecond().close(); - } else - LogManager.instance().log(this, Level.INFO, "PSQL: Blocked unauthorized canceling session " + pid); - } else - LogManager.instance().log(this, Level.INFO, "PSQL: Session " + pid + " not found"); + } else LogManager.instance().log(this, Level.INFO, "PSQL: Blocked unauthorized canceling session " + pid); + } else LogManager.instance().log(this, Level.INFO, "PSQL: Session " + pid + " not found"); close(); return false; @@ -1026,13 +949,11 @@ private void writeMessage(final String messageName, final WriteMessageCallback c try { channel.writeByte((byte) messageCode); channel.writeUnsignedInt((int) length); - if (callback != null) - callback.write(); + if (callback != null) callback.write(); channel.flush(); - if (DEBUG) - LogManager.instance().log(this, Level.INFO, "PSQL:-> %s (%s - %s) (thread=%s)", null, messageName, messageCode, - FileUtils.getSizeAsString(length), Thread.currentThread().getId()); + if (DEBUG) LogManager.instance().log(this, Level.INFO, "PSQL:-> %s (%s - %s) (thread=%s)", null, messageName, messageCode, + FileUtils.getSizeAsString(length), Thread.currentThread().getId()); } catch (final IOException e) { setErrorInTx(); @@ -1057,8 +978,7 @@ private boolean readMessage(final String messageName, final ReadMessageCallback if (!valid) { // READ TILL THE END OF THE MESSAGE - if (length > 4) - readBytes((int) (length - 4)); + if (length > 4) readBytes((int) (length - 4)); throw new PostgresProtocolException("Unexpected message type '" + type + "' for message " + messageName); } } @@ -1106,8 +1026,7 @@ private String readString() throws IOException { int len = 0; for (; len < buffer.length; len++) { final int b = readNextByte(); - if (b == 0) - return new String(buffer, 0, len, DatabaseFactory.getDefaultCharset()); + if (b == 0) return new String(buffer, 0, len, DatabaseFactory.getDefaultCharset()); buffer[len] = (byte) b; } @@ -1137,16 +1056,11 @@ private void readBytes(final int len) throws IOException { private void writeCommandComplete(final String queryText, final int resultSetCount) { final String upperCaseText = queryText.toUpperCase(Locale.ENGLISH); String tag = ""; - if (upperCaseText.startsWith("CREATE VERTEX") || upperCaseText.startsWith("INSERT INTO")) - tag = "INSERT 0 " + resultSetCount; - else if (upperCaseText.startsWith("SELECT") || upperCaseText.startsWith("MATCH")) - tag = "SELECT " + resultSetCount; - else if (upperCaseText.startsWith("UPDATE")) - tag = "UPDATE " + resultSetCount; - else if (upperCaseText.startsWith("DELETE")) - tag = "DELETE " + resultSetCount; - else if (upperCaseText.equals("BEGIN") || upperCaseText.equals("BEGIN TRANSACTION")) - tag = "BEGIN"; + if (upperCaseText.startsWith("CREATE VERTEX") || upperCaseText.startsWith("INSERT INTO")) tag = "INSERT 0 " + resultSetCount; + else if (upperCaseText.startsWith("SELECT") || upperCaseText.startsWith("MATCH")) tag = "SELECT " + resultSetCount; + else if (upperCaseText.startsWith("UPDATE")) tag = "UPDATE " + resultSetCount; + else if (upperCaseText.startsWith("DELETE")) tag = "DELETE " + resultSetCount; + else if (upperCaseText.equals("BEGIN") || upperCaseText.equals("BEGIN TRANSACTION")) tag = "BEGIN"; final String finalTag = tag; writeMessage("command complete", () -> writeString(finalTag), 'C', 4 + tag.length() + 1); @@ -1157,10 +1071,8 @@ private void writeNoData() { } private PostgresPortal getPortal(final String name, final boolean remove) { - if (remove) - return portals.remove(name); - else - return portals.get(name); + if (remove) return portals.remove(name); + else return portals.get(name); } private void createResultSet(final PostgresPortal portal, final Object... elements) { @@ -1170,8 +1082,7 @@ private void createResultSet(final PostgresPortal portal, final Object... elemen } private List createResultSet(final Object... elements) { - if (elements.length % 2 != 0) - throw new IllegalArgumentException("Resultset elements must be in pairs"); + if (elements.length % 2 != 0) throw new IllegalArgumentException("Resultset elements must be in pairs"); final List resultSet = new ArrayList<>(); for (int i = 0; i < elements.length; i += 2) { @@ -1182,23 +1093,20 @@ private List createResultSet(final Object... elements) { return resultSet; } - private String[] getLanguageAndQuery(final String query) { + private Query getLanguageAndQuery(final String query) { String language = "sql"; String queryText = query; - if (queryText.startsWith("{cypher}")) { - language = "cypher"; - queryText = queryText.substring("{cypher}".length()); - } else if (queryText.startsWith("{gremlin}")) { - language = "gremlin"; - queryText = queryText.substring("{gremlin}".length()); - } else if (queryText.startsWith("{mongo}")) { - language = "mongo"; - queryText = queryText.substring("{mongo}".length()); - } else if (queryText.startsWith("{graphql}")) { - language = "graphql"; - queryText = queryText.substring("{graphql}".length()); + + // Regular expression to match language prefixes + Pattern pattern = Pattern.compile("\\{(\\w+)\\}"); + Matcher matcher = pattern.matcher(query); + + if (matcher.find()) { + language = matcher.group(1); + queryText = query.substring(matcher.end()); } - return new String[] { language, queryText }; + + return new Query(language, queryText); } private void emptyQueryResponse() { @@ -1210,7 +1118,10 @@ private void portalSuspendedResponse() { } private void setErrorInTx() { - if (explicitTransactionStarted) - errorInTransaction = true; + if (explicitTransactionStarted) errorInTransaction = true; + } + + private record Query(String language, String query) { } + } diff --git a/server/src/main/java/com/arcadedb/server/ha/message/ServerShutdownRequest.java b/server/src/main/java/com/arcadedb/server/ha/message/ServerShutdownRequest.java index 62edc91a91..57ff476861 100755 --- a/server/src/main/java/com/arcadedb/server/ha/message/ServerShutdownRequest.java +++ b/server/src/main/java/com/arcadedb/server/ha/message/ServerShutdownRequest.java @@ -24,8 +24,6 @@ import java.util.logging.*; public class ServerShutdownRequest extends HAAbstractCommand { - public ServerShutdownRequest() { - } @Override public HACommand execute(final HAServer server, final String remoteServerName, final long messageNumber) {