From d0e17474d232857d9c183a9cd890f03551044e4c Mon Sep 17 00:00:00 2001 From: gspikehalo <2318002579@qq.com> Date: Sun, 16 Feb 2025 18:00:08 -0800 Subject: [PATCH 1/8] update tables --- .../texera/dao/jooq/generated/Indexes.java | 8 + .../ics/texera/dao/jooq/generated/Keys.java | 14 ++ .../ics/texera/dao/jooq/generated/Tables.java | 12 ++ .../texera/dao/jooq/generated/TexeraDb.java | 16 +- .../generated/tables/DatasetUserLikes.java | 161 +++++++++++++++++ .../generated/tables/DatasetViewCount.java | 157 +++++++++++++++++ .../tables/daos/DatasetUserLikesDao.java | 70 ++++++++ .../tables/daos/DatasetViewCountDao.java | 76 ++++++++ .../tables/interfaces/IDatasetUserLikes.java | 51 ++++++ .../tables/interfaces/IDatasetViewCount.java | 51 ++++++ .../tables/pojos/DatasetUserLikes.java | 84 +++++++++ .../tables/pojos/DatasetViewCount.java | 84 +++++++++ .../records/DatasetUserLikesRecord.java | 165 +++++++++++++++++ .../records/DatasetViewCountRecord.java | 166 ++++++++++++++++++ 14 files changed, 1114 insertions(+), 1 deletion(-) create mode 100644 core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/DatasetUserLikes.java create mode 100644 core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/DatasetViewCount.java create mode 100644 core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/daos/DatasetUserLikesDao.java create mode 100644 core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/daos/DatasetViewCountDao.java create mode 100644 core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/interfaces/IDatasetUserLikes.java create mode 100644 core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/interfaces/IDatasetViewCount.java create mode 100644 core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/pojos/DatasetUserLikes.java create mode 100644 core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/pojos/DatasetViewCount.java create mode 100644 core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/records/DatasetUserLikesRecord.java create mode 100644 core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/records/DatasetViewCountRecord.java diff --git a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/Indexes.java b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/Indexes.java index dd2593df8c..f3b7cf15bf 100644 --- a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/Indexes.java +++ b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/Indexes.java @@ -6,7 +6,9 @@ import edu.uci.ics.texera.dao.jooq.generated.tables.Dataset; import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetUserAccess; +import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetUserLikes; import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetVersion; +import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetViewCount; import edu.uci.ics.texera.dao.jooq.generated.tables.OperatorExecutions; import edu.uci.ics.texera.dao.jooq.generated.tables.OperatorPortExecutions; import edu.uci.ics.texera.dao.jooq.generated.tables.Project; @@ -44,9 +46,12 @@ public class Indexes { public static final Index DATASET_PRIMARY = Indexes0.DATASET_PRIMARY; public static final Index DATASET_USER_ACCESS_PRIMARY = Indexes0.DATASET_USER_ACCESS_PRIMARY; public static final Index DATASET_USER_ACCESS_UID = Indexes0.DATASET_USER_ACCESS_UID; + public static final Index DATASET_USER_LIKES_DID = Indexes0.DATASET_USER_LIKES_DID; + public static final Index DATASET_USER_LIKES_PRIMARY = Indexes0.DATASET_USER_LIKES_PRIMARY; public static final Index DATASET_VERSION_DID = Indexes0.DATASET_VERSION_DID; public static final Index DATASET_VERSION_IDX_DATASET_VERSION_NAME = Indexes0.DATASET_VERSION_IDX_DATASET_VERSION_NAME; public static final Index DATASET_VERSION_PRIMARY = Indexes0.DATASET_VERSION_PRIMARY; + public static final Index DATASET_VIEW_COUNT_PRIMARY = Indexes0.DATASET_VIEW_COUNT_PRIMARY; public static final Index OPERATOR_EXECUTIONS_WORKFLOW_EXECUTION_ID = Indexes0.OPERATOR_EXECUTIONS_WORKFLOW_EXECUTION_ID; public static final Index OPERATOR_PORT_EXECUTIONS_WORKFLOW_EXECUTION_ID = Indexes0.OPERATOR_PORT_EXECUTIONS_WORKFLOW_EXECUTION_ID; public static final Index PROJECT_IDX_USER_PROJECT_NAME_DESCRIPTION = Indexes0.PROJECT_IDX_USER_PROJECT_NAME_DESCRIPTION; @@ -89,9 +94,12 @@ private static class Indexes0 { public static Index DATASET_PRIMARY = Internal.createIndex("PRIMARY", Dataset.DATASET, new OrderField[] { Dataset.DATASET.DID }, true); public static Index DATASET_USER_ACCESS_PRIMARY = Internal.createIndex("PRIMARY", DatasetUserAccess.DATASET_USER_ACCESS, new OrderField[] { DatasetUserAccess.DATASET_USER_ACCESS.DID, DatasetUserAccess.DATASET_USER_ACCESS.UID }, true); public static Index DATASET_USER_ACCESS_UID = Internal.createIndex("uid", DatasetUserAccess.DATASET_USER_ACCESS, new OrderField[] { DatasetUserAccess.DATASET_USER_ACCESS.UID }, false); + public static Index DATASET_USER_LIKES_DID = Internal.createIndex("did", DatasetUserLikes.DATASET_USER_LIKES, new OrderField[] { DatasetUserLikes.DATASET_USER_LIKES.DID }, false); + public static Index DATASET_USER_LIKES_PRIMARY = Internal.createIndex("PRIMARY", DatasetUserLikes.DATASET_USER_LIKES, new OrderField[] { DatasetUserLikes.DATASET_USER_LIKES.UID, DatasetUserLikes.DATASET_USER_LIKES.DID }, true); public static Index DATASET_VERSION_DID = Internal.createIndex("did", DatasetVersion.DATASET_VERSION, new OrderField[] { DatasetVersion.DATASET_VERSION.DID }, false); public static Index DATASET_VERSION_IDX_DATASET_VERSION_NAME = Internal.createIndex("idx_dataset_version_name", DatasetVersion.DATASET_VERSION, new OrderField[] { DatasetVersion.DATASET_VERSION.NAME }, false); public static Index DATASET_VERSION_PRIMARY = Internal.createIndex("PRIMARY", DatasetVersion.DATASET_VERSION, new OrderField[] { DatasetVersion.DATASET_VERSION.DVID }, true); + public static Index DATASET_VIEW_COUNT_PRIMARY = Internal.createIndex("PRIMARY", DatasetViewCount.DATASET_VIEW_COUNT, new OrderField[] { DatasetViewCount.DATASET_VIEW_COUNT.DID }, true); public static Index OPERATOR_EXECUTIONS_WORKFLOW_EXECUTION_ID = Internal.createIndex("workflow_execution_id", OperatorExecutions.OPERATOR_EXECUTIONS, new OrderField[] { OperatorExecutions.OPERATOR_EXECUTIONS.WORKFLOW_EXECUTION_ID, OperatorExecutions.OPERATOR_EXECUTIONS.OPERATOR_ID }, true); public static Index OPERATOR_PORT_EXECUTIONS_WORKFLOW_EXECUTION_ID = Internal.createIndex("workflow_execution_id", OperatorPortExecutions.OPERATOR_PORT_EXECUTIONS, new OrderField[] { OperatorPortExecutions.OPERATOR_PORT_EXECUTIONS.WORKFLOW_EXECUTION_ID, OperatorPortExecutions.OPERATOR_PORT_EXECUTIONS.OPERATOR_ID, OperatorPortExecutions.OPERATOR_PORT_EXECUTIONS.PORT_ID }, true); public static Index PROJECT_IDX_USER_PROJECT_NAME_DESCRIPTION = Internal.createIndex("idx_user_project_name_description", Project.PROJECT, new OrderField[] { Project.PROJECT.NAME, Project.PROJECT.DESCRIPTION }, false); diff --git a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/Keys.java b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/Keys.java index 89bc0d1cd8..c2def618e6 100644 --- a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/Keys.java +++ b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/Keys.java @@ -6,7 +6,9 @@ import edu.uci.ics.texera.dao.jooq.generated.tables.Dataset; import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetUserAccess; +import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetUserLikes; import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetVersion; +import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetViewCount; import edu.uci.ics.texera.dao.jooq.generated.tables.OperatorExecutions; import edu.uci.ics.texera.dao.jooq.generated.tables.OperatorPortExecutions; import edu.uci.ics.texera.dao.jooq.generated.tables.Project; @@ -25,7 +27,9 @@ import edu.uci.ics.texera.dao.jooq.generated.tables.WorkflowViewCount; import edu.uci.ics.texera.dao.jooq.generated.tables.records.DatasetRecord; import edu.uci.ics.texera.dao.jooq.generated.tables.records.DatasetUserAccessRecord; +import edu.uci.ics.texera.dao.jooq.generated.tables.records.DatasetUserLikesRecord; import edu.uci.ics.texera.dao.jooq.generated.tables.records.DatasetVersionRecord; +import edu.uci.ics.texera.dao.jooq.generated.tables.records.DatasetViewCountRecord; import edu.uci.ics.texera.dao.jooq.generated.tables.records.OperatorExecutionsRecord; import edu.uci.ics.texera.dao.jooq.generated.tables.records.OperatorPortExecutionsRecord; import edu.uci.ics.texera.dao.jooq.generated.tables.records.ProjectRecord; @@ -75,7 +79,9 @@ public class Keys { public static final UniqueKey KEY_DATASET_PRIMARY = UniqueKeys0.KEY_DATASET_PRIMARY; public static final UniqueKey KEY_DATASET_USER_ACCESS_PRIMARY = UniqueKeys0.KEY_DATASET_USER_ACCESS_PRIMARY; + public static final UniqueKey KEY_DATASET_USER_LIKES_PRIMARY = UniqueKeys0.KEY_DATASET_USER_LIKES_PRIMARY; public static final UniqueKey KEY_DATASET_VERSION_PRIMARY = UniqueKeys0.KEY_DATASET_VERSION_PRIMARY; + public static final UniqueKey KEY_DATASET_VIEW_COUNT_PRIMARY = UniqueKeys0.KEY_DATASET_VIEW_COUNT_PRIMARY; public static final UniqueKey KEY_OPERATOR_EXECUTIONS_WORKFLOW_EXECUTION_ID = UniqueKeys0.KEY_OPERATOR_EXECUTIONS_WORKFLOW_EXECUTION_ID; public static final UniqueKey KEY_OPERATOR_PORT_EXECUTIONS_WORKFLOW_EXECUTION_ID = UniqueKeys0.KEY_OPERATOR_PORT_EXECUTIONS_WORKFLOW_EXECUTION_ID; public static final UniqueKey KEY_PROJECT_PRIMARY = UniqueKeys0.KEY_PROJECT_PRIMARY; @@ -103,7 +109,10 @@ public class Keys { public static final ForeignKey DATASET_IBFK_1 = ForeignKeys0.DATASET_IBFK_1; public static final ForeignKey DATASET_USER_ACCESS_IBFK_1 = ForeignKeys0.DATASET_USER_ACCESS_IBFK_1; public static final ForeignKey DATASET_USER_ACCESS_IBFK_2 = ForeignKeys0.DATASET_USER_ACCESS_IBFK_2; + public static final ForeignKey DATASET_USER_LIKES_IBFK_1 = ForeignKeys0.DATASET_USER_LIKES_IBFK_1; + public static final ForeignKey DATASET_USER_LIKES_IBFK_2 = ForeignKeys0.DATASET_USER_LIKES_IBFK_2; public static final ForeignKey DATASET_VERSION_IBFK_1 = ForeignKeys0.DATASET_VERSION_IBFK_1; + public static final ForeignKey DATASET_VIEW_COUNT_IBFK_1 = ForeignKeys0.DATASET_VIEW_COUNT_IBFK_1; public static final ForeignKey OPERATOR_EXECUTIONS_IBFK_1 = ForeignKeys0.OPERATOR_EXECUTIONS_IBFK_1; public static final ForeignKey OPERATOR_PORT_EXECUTIONS_IBFK_1 = ForeignKeys0.OPERATOR_PORT_EXECUTIONS_IBFK_1; public static final ForeignKey PROJECT_IBFK_1 = ForeignKeys0.PROJECT_IBFK_1; @@ -143,7 +152,9 @@ private static class Identities0 { private static class UniqueKeys0 { public static final UniqueKey KEY_DATASET_PRIMARY = Internal.createUniqueKey(Dataset.DATASET, "KEY_dataset_PRIMARY", Dataset.DATASET.DID); public static final UniqueKey KEY_DATASET_USER_ACCESS_PRIMARY = Internal.createUniqueKey(DatasetUserAccess.DATASET_USER_ACCESS, "KEY_dataset_user_access_PRIMARY", DatasetUserAccess.DATASET_USER_ACCESS.DID, DatasetUserAccess.DATASET_USER_ACCESS.UID); + public static final UniqueKey KEY_DATASET_USER_LIKES_PRIMARY = Internal.createUniqueKey(DatasetUserLikes.DATASET_USER_LIKES, "KEY_dataset_user_likes_PRIMARY", DatasetUserLikes.DATASET_USER_LIKES.UID, DatasetUserLikes.DATASET_USER_LIKES.DID); public static final UniqueKey KEY_DATASET_VERSION_PRIMARY = Internal.createUniqueKey(DatasetVersion.DATASET_VERSION, "KEY_dataset_version_PRIMARY", DatasetVersion.DATASET_VERSION.DVID); + public static final UniqueKey KEY_DATASET_VIEW_COUNT_PRIMARY = Internal.createUniqueKey(DatasetViewCount.DATASET_VIEW_COUNT, "KEY_dataset_view_count_PRIMARY", DatasetViewCount.DATASET_VIEW_COUNT.DID); public static final UniqueKey KEY_OPERATOR_EXECUTIONS_WORKFLOW_EXECUTION_ID = Internal.createUniqueKey(OperatorExecutions.OPERATOR_EXECUTIONS, "KEY_operator_executions_workflow_execution_id", OperatorExecutions.OPERATOR_EXECUTIONS.WORKFLOW_EXECUTION_ID, OperatorExecutions.OPERATOR_EXECUTIONS.OPERATOR_ID); public static final UniqueKey KEY_OPERATOR_PORT_EXECUTIONS_WORKFLOW_EXECUTION_ID = Internal.createUniqueKey(OperatorPortExecutions.OPERATOR_PORT_EXECUTIONS, "KEY_operator_port_executions_workflow_execution_id", OperatorPortExecutions.OPERATOR_PORT_EXECUTIONS.WORKFLOW_EXECUTION_ID, OperatorPortExecutions.OPERATOR_PORT_EXECUTIONS.OPERATOR_ID, OperatorPortExecutions.OPERATOR_PORT_EXECUTIONS.PORT_ID); public static final UniqueKey KEY_PROJECT_PRIMARY = Internal.createUniqueKey(Project.PROJECT, "KEY_project_PRIMARY", Project.PROJECT.PID); @@ -169,7 +180,10 @@ private static class ForeignKeys0 { public static final ForeignKey DATASET_IBFK_1 = Internal.createForeignKey(edu.uci.ics.texera.dao.jooq.generated.Keys.KEY_USER_PRIMARY, Dataset.DATASET, "dataset_ibfk_1", Dataset.DATASET.OWNER_UID); public static final ForeignKey DATASET_USER_ACCESS_IBFK_1 = Internal.createForeignKey(edu.uci.ics.texera.dao.jooq.generated.Keys.KEY_DATASET_PRIMARY, DatasetUserAccess.DATASET_USER_ACCESS, "dataset_user_access_ibfk_1", DatasetUserAccess.DATASET_USER_ACCESS.DID); public static final ForeignKey DATASET_USER_ACCESS_IBFK_2 = Internal.createForeignKey(edu.uci.ics.texera.dao.jooq.generated.Keys.KEY_USER_PRIMARY, DatasetUserAccess.DATASET_USER_ACCESS, "dataset_user_access_ibfk_2", DatasetUserAccess.DATASET_USER_ACCESS.UID); + public static final ForeignKey DATASET_USER_LIKES_IBFK_1 = Internal.createForeignKey(edu.uci.ics.texera.dao.jooq.generated.Keys.KEY_USER_PRIMARY, DatasetUserLikes.DATASET_USER_LIKES, "dataset_user_likes_ibfk_1", DatasetUserLikes.DATASET_USER_LIKES.UID); + public static final ForeignKey DATASET_USER_LIKES_IBFK_2 = Internal.createForeignKey(edu.uci.ics.texera.dao.jooq.generated.Keys.KEY_DATASET_PRIMARY, DatasetUserLikes.DATASET_USER_LIKES, "dataset_user_likes_ibfk_2", DatasetUserLikes.DATASET_USER_LIKES.DID); public static final ForeignKey DATASET_VERSION_IBFK_1 = Internal.createForeignKey(edu.uci.ics.texera.dao.jooq.generated.Keys.KEY_DATASET_PRIMARY, DatasetVersion.DATASET_VERSION, "dataset_version_ibfk_1", DatasetVersion.DATASET_VERSION.DID); + public static final ForeignKey DATASET_VIEW_COUNT_IBFK_1 = Internal.createForeignKey(edu.uci.ics.texera.dao.jooq.generated.Keys.KEY_DATASET_PRIMARY, DatasetViewCount.DATASET_VIEW_COUNT, "dataset_view_count_ibfk_1", DatasetViewCount.DATASET_VIEW_COUNT.DID); public static final ForeignKey OPERATOR_EXECUTIONS_IBFK_1 = Internal.createForeignKey(edu.uci.ics.texera.dao.jooq.generated.Keys.KEY_WORKFLOW_EXECUTIONS_PRIMARY, OperatorExecutions.OPERATOR_EXECUTIONS, "operator_executions_ibfk_1", OperatorExecutions.OPERATOR_EXECUTIONS.WORKFLOW_EXECUTION_ID); public static final ForeignKey OPERATOR_PORT_EXECUTIONS_IBFK_1 = Internal.createForeignKey(edu.uci.ics.texera.dao.jooq.generated.Keys.KEY_WORKFLOW_EXECUTIONS_PRIMARY, OperatorPortExecutions.OPERATOR_PORT_EXECUTIONS, "operator_port_executions_ibfk_1", OperatorPortExecutions.OPERATOR_PORT_EXECUTIONS.WORKFLOW_EXECUTION_ID); public static final ForeignKey PROJECT_IBFK_1 = Internal.createForeignKey(edu.uci.ics.texera.dao.jooq.generated.Keys.KEY_USER_PRIMARY, Project.PROJECT, "project_ibfk_1", Project.PROJECT.OWNER_ID); diff --git a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/Tables.java b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/Tables.java index 2e60bdb800..b8385eca46 100644 --- a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/Tables.java +++ b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/Tables.java @@ -6,7 +6,9 @@ import edu.uci.ics.texera.dao.jooq.generated.tables.Dataset; import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetUserAccess; +import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetUserLikes; import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetVersion; +import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetViewCount; import edu.uci.ics.texera.dao.jooq.generated.tables.OperatorExecutions; import edu.uci.ics.texera.dao.jooq.generated.tables.OperatorPortExecutions; import edu.uci.ics.texera.dao.jooq.generated.tables.Project; @@ -42,11 +44,21 @@ public class Tables { */ public static final DatasetUserAccess DATASET_USER_ACCESS = DatasetUserAccess.DATASET_USER_ACCESS; + /** + * The table texera_db.dataset_user_likes. + */ + public static final DatasetUserLikes DATASET_USER_LIKES = DatasetUserLikes.DATASET_USER_LIKES; + /** * The table texera_db.dataset_version. */ public static final DatasetVersion DATASET_VERSION = DatasetVersion.DATASET_VERSION; + /** + * The table texera_db.dataset_view_count. + */ + public static final DatasetViewCount DATASET_VIEW_COUNT = DatasetViewCount.DATASET_VIEW_COUNT; + /** * The table texera_db.operator_executions. */ diff --git a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/TexeraDb.java b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/TexeraDb.java index 4d83cd80d6..e6eb7f3411 100644 --- a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/TexeraDb.java +++ b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/TexeraDb.java @@ -6,7 +6,9 @@ import edu.uci.ics.texera.dao.jooq.generated.tables.Dataset; import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetUserAccess; +import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetUserLikes; import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetVersion; +import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetViewCount; import edu.uci.ics.texera.dao.jooq.generated.tables.OperatorExecutions; import edu.uci.ics.texera.dao.jooq.generated.tables.OperatorPortExecutions; import edu.uci.ics.texera.dao.jooq.generated.tables.Project; @@ -40,7 +42,7 @@ @SuppressWarnings({ "all", "unchecked", "rawtypes" }) public class TexeraDb extends SchemaImpl { - private static final long serialVersionUID = -745081464; + private static final long serialVersionUID = -590590918; /** * The reference instance of texera_db @@ -57,11 +59,21 @@ public class TexeraDb extends SchemaImpl { */ public final DatasetUserAccess DATASET_USER_ACCESS = edu.uci.ics.texera.dao.jooq.generated.tables.DatasetUserAccess.DATASET_USER_ACCESS; + /** + * The table texera_db.dataset_user_likes. + */ + public final DatasetUserLikes DATASET_USER_LIKES = edu.uci.ics.texera.dao.jooq.generated.tables.DatasetUserLikes.DATASET_USER_LIKES; + /** * The table texera_db.dataset_version. */ public final DatasetVersion DATASET_VERSION = edu.uci.ics.texera.dao.jooq.generated.tables.DatasetVersion.DATASET_VERSION; + /** + * The table texera_db.dataset_view_count. + */ + public final DatasetViewCount DATASET_VIEW_COUNT = edu.uci.ics.texera.dao.jooq.generated.tables.DatasetViewCount.DATASET_VIEW_COUNT; + /** * The table texera_db.operator_executions. */ @@ -171,7 +183,9 @@ private final List> getTables0() { return Arrays.>asList( Dataset.DATASET, DatasetUserAccess.DATASET_USER_ACCESS, + DatasetUserLikes.DATASET_USER_LIKES, DatasetVersion.DATASET_VERSION, + DatasetViewCount.DATASET_VIEW_COUNT, OperatorExecutions.OPERATOR_EXECUTIONS, OperatorPortExecutions.OPERATOR_PORT_EXECUTIONS, Project.PROJECT, diff --git a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/DatasetUserLikes.java b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/DatasetUserLikes.java new file mode 100644 index 0000000000..ec7ef7aa30 --- /dev/null +++ b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/DatasetUserLikes.java @@ -0,0 +1,161 @@ +/* + * This file is generated by jOOQ. + */ +package edu.uci.ics.texera.dao.jooq.generated.tables; + + +import edu.uci.ics.texera.dao.jooq.generated.Indexes; +import edu.uci.ics.texera.dao.jooq.generated.Keys; +import edu.uci.ics.texera.dao.jooq.generated.TexeraDb; +import edu.uci.ics.texera.dao.jooq.generated.tables.records.DatasetUserLikesRecord; + +import java.util.Arrays; +import java.util.List; + +import org.jooq.Field; +import org.jooq.ForeignKey; +import org.jooq.Index; +import org.jooq.Name; +import org.jooq.Record; +import org.jooq.Row2; +import org.jooq.Schema; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.UniqueKey; +import org.jooq.impl.DSL; +import org.jooq.impl.TableImpl; +import org.jooq.types.UInteger; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class DatasetUserLikes extends TableImpl { + + private static final long serialVersionUID = 566607224; + + /** + * The reference instance of texera_db.dataset_user_likes + */ + public static final DatasetUserLikes DATASET_USER_LIKES = new DatasetUserLikes(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return DatasetUserLikesRecord.class; + } + + /** + * The column texera_db.dataset_user_likes.uid. + */ + public final TableField UID = createField(DSL.name("uid"), org.jooq.impl.SQLDataType.INTEGERUNSIGNED.nullable(false), this, ""); + + /** + * The column texera_db.dataset_user_likes.did. + */ + public final TableField DID = createField(DSL.name("did"), org.jooq.impl.SQLDataType.INTEGERUNSIGNED.nullable(false), this, ""); + + /** + * Create a texera_db.dataset_user_likes table reference + */ + public DatasetUserLikes() { + this(DSL.name("dataset_user_likes"), null); + } + + /** + * Create an aliased texera_db.dataset_user_likes table reference + */ + public DatasetUserLikes(String alias) { + this(DSL.name(alias), DATASET_USER_LIKES); + } + + /** + * Create an aliased texera_db.dataset_user_likes table reference + */ + public DatasetUserLikes(Name alias) { + this(alias, DATASET_USER_LIKES); + } + + private DatasetUserLikes(Name alias, Table aliased) { + this(alias, aliased, null); + } + + private DatasetUserLikes(Name alias, Table aliased, Field[] parameters) { + super(alias, null, aliased, parameters, DSL.comment("")); + } + + public DatasetUserLikes(Table child, ForeignKey key) { + super(child, key, DATASET_USER_LIKES); + } + + @Override + public Schema getSchema() { + return TexeraDb.TEXERA_DB; + } + + @Override + public List getIndexes() { + return Arrays.asList(Indexes.DATASET_USER_LIKES_DID, Indexes.DATASET_USER_LIKES_PRIMARY); + } + + @Override + public UniqueKey getPrimaryKey() { + return Keys.KEY_DATASET_USER_LIKES_PRIMARY; + } + + @Override + public List> getKeys() { + return Arrays.>asList(Keys.KEY_DATASET_USER_LIKES_PRIMARY); + } + + @Override + public List> getReferences() { + return Arrays.>asList(Keys.DATASET_USER_LIKES_IBFK_1, Keys.DATASET_USER_LIKES_IBFK_2); + } + + public User user() { + return new User(this, Keys.DATASET_USER_LIKES_IBFK_1); + } + + public Dataset dataset() { + return new Dataset(this, Keys.DATASET_USER_LIKES_IBFK_2); + } + + @Override + public DatasetUserLikes as(String alias) { + return new DatasetUserLikes(DSL.name(alias), this); + } + + @Override + public DatasetUserLikes as(Name alias) { + return new DatasetUserLikes(alias, this); + } + + /** + * Rename this table + */ + @Override + public DatasetUserLikes rename(String name) { + return new DatasetUserLikes(DSL.name(name), null); + } + + /** + * Rename this table + */ + @Override + public DatasetUserLikes rename(Name name) { + return new DatasetUserLikes(name, null); + } + + // ------------------------------------------------------------------------- + // Row2 type methods + // ------------------------------------------------------------------------- + + @Override + public Row2 fieldsRow() { + return (Row2) super.fieldsRow(); + } +} diff --git a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/DatasetViewCount.java b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/DatasetViewCount.java new file mode 100644 index 0000000000..60ddcb39e7 --- /dev/null +++ b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/DatasetViewCount.java @@ -0,0 +1,157 @@ +/* + * This file is generated by jOOQ. + */ +package edu.uci.ics.texera.dao.jooq.generated.tables; + + +import edu.uci.ics.texera.dao.jooq.generated.Indexes; +import edu.uci.ics.texera.dao.jooq.generated.Keys; +import edu.uci.ics.texera.dao.jooq.generated.TexeraDb; +import edu.uci.ics.texera.dao.jooq.generated.tables.records.DatasetViewCountRecord; + +import java.util.Arrays; +import java.util.List; + +import org.jooq.Field; +import org.jooq.ForeignKey; +import org.jooq.Index; +import org.jooq.Name; +import org.jooq.Record; +import org.jooq.Row2; +import org.jooq.Schema; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.UniqueKey; +import org.jooq.impl.DSL; +import org.jooq.impl.TableImpl; +import org.jooq.types.UInteger; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class DatasetViewCount extends TableImpl { + + private static final long serialVersionUID = 2087672115; + + /** + * The reference instance of texera_db.dataset_view_count + */ + public static final DatasetViewCount DATASET_VIEW_COUNT = new DatasetViewCount(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return DatasetViewCountRecord.class; + } + + /** + * The column texera_db.dataset_view_count.did. + */ + public final TableField DID = createField(DSL.name("did"), org.jooq.impl.SQLDataType.INTEGERUNSIGNED.nullable(false), this, ""); + + /** + * The column texera_db.dataset_view_count.view_count. + */ + public final TableField VIEW_COUNT = createField(DSL.name("view_count"), org.jooq.impl.SQLDataType.INTEGERUNSIGNED.nullable(false).defaultValue(org.jooq.impl.DSL.inline("0", org.jooq.impl.SQLDataType.INTEGERUNSIGNED)), this, ""); + + /** + * Create a texera_db.dataset_view_count table reference + */ + public DatasetViewCount() { + this(DSL.name("dataset_view_count"), null); + } + + /** + * Create an aliased texera_db.dataset_view_count table reference + */ + public DatasetViewCount(String alias) { + this(DSL.name(alias), DATASET_VIEW_COUNT); + } + + /** + * Create an aliased texera_db.dataset_view_count table reference + */ + public DatasetViewCount(Name alias) { + this(alias, DATASET_VIEW_COUNT); + } + + private DatasetViewCount(Name alias, Table aliased) { + this(alias, aliased, null); + } + + private DatasetViewCount(Name alias, Table aliased, Field[] parameters) { + super(alias, null, aliased, parameters, DSL.comment("")); + } + + public DatasetViewCount(Table child, ForeignKey key) { + super(child, key, DATASET_VIEW_COUNT); + } + + @Override + public Schema getSchema() { + return TexeraDb.TEXERA_DB; + } + + @Override + public List getIndexes() { + return Arrays.asList(Indexes.DATASET_VIEW_COUNT_PRIMARY); + } + + @Override + public UniqueKey getPrimaryKey() { + return Keys.KEY_DATASET_VIEW_COUNT_PRIMARY; + } + + @Override + public List> getKeys() { + return Arrays.>asList(Keys.KEY_DATASET_VIEW_COUNT_PRIMARY); + } + + @Override + public List> getReferences() { + return Arrays.>asList(Keys.DATASET_VIEW_COUNT_IBFK_1); + } + + public Dataset dataset() { + return new Dataset(this, Keys.DATASET_VIEW_COUNT_IBFK_1); + } + + @Override + public DatasetViewCount as(String alias) { + return new DatasetViewCount(DSL.name(alias), this); + } + + @Override + public DatasetViewCount as(Name alias) { + return new DatasetViewCount(alias, this); + } + + /** + * Rename this table + */ + @Override + public DatasetViewCount rename(String name) { + return new DatasetViewCount(DSL.name(name), null); + } + + /** + * Rename this table + */ + @Override + public DatasetViewCount rename(Name name) { + return new DatasetViewCount(name, null); + } + + // ------------------------------------------------------------------------- + // Row2 type methods + // ------------------------------------------------------------------------- + + @Override + public Row2 fieldsRow() { + return (Row2) super.fieldsRow(); + } +} diff --git a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/daos/DatasetUserLikesDao.java b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/daos/DatasetUserLikesDao.java new file mode 100644 index 0000000000..2285b882dc --- /dev/null +++ b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/daos/DatasetUserLikesDao.java @@ -0,0 +1,70 @@ +/* + * This file is generated by jOOQ. + */ +package edu.uci.ics.texera.dao.jooq.generated.tables.daos; + + +import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetUserLikes; +import edu.uci.ics.texera.dao.jooq.generated.tables.records.DatasetUserLikesRecord; + +import java.util.List; + +import org.jooq.Configuration; +import org.jooq.Record2; +import org.jooq.impl.DAOImpl; +import org.jooq.types.UInteger; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class DatasetUserLikesDao extends DAOImpl> { + + /** + * Create a new DatasetUserLikesDao without any configuration + */ + public DatasetUserLikesDao() { + super(DatasetUserLikes.DATASET_USER_LIKES, edu.uci.ics.texera.dao.jooq.generated.tables.pojos.DatasetUserLikes.class); + } + + /** + * Create a new DatasetUserLikesDao with an attached configuration + */ + public DatasetUserLikesDao(Configuration configuration) { + super(DatasetUserLikes.DATASET_USER_LIKES, edu.uci.ics.texera.dao.jooq.generated.tables.pojos.DatasetUserLikes.class, configuration); + } + + @Override + public Record2 getId(edu.uci.ics.texera.dao.jooq.generated.tables.pojos.DatasetUserLikes object) { + return compositeKeyRecord(object.getUid(), object.getDid()); + } + + /** + * Fetch records that have uid BETWEEN lowerInclusive AND upperInclusive + */ + public List fetchRangeOfUid(UInteger lowerInclusive, UInteger upperInclusive) { + return fetchRange(DatasetUserLikes.DATASET_USER_LIKES.UID, lowerInclusive, upperInclusive); + } + + /** + * Fetch records that have uid IN (values) + */ + public List fetchByUid(UInteger... values) { + return fetch(DatasetUserLikes.DATASET_USER_LIKES.UID, values); + } + + /** + * Fetch records that have did BETWEEN lowerInclusive AND upperInclusive + */ + public List fetchRangeOfDid(UInteger lowerInclusive, UInteger upperInclusive) { + return fetchRange(DatasetUserLikes.DATASET_USER_LIKES.DID, lowerInclusive, upperInclusive); + } + + /** + * Fetch records that have did IN (values) + */ + public List fetchByDid(UInteger... values) { + return fetch(DatasetUserLikes.DATASET_USER_LIKES.DID, values); + } +} diff --git a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/daos/DatasetViewCountDao.java b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/daos/DatasetViewCountDao.java new file mode 100644 index 0000000000..054b783c92 --- /dev/null +++ b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/daos/DatasetViewCountDao.java @@ -0,0 +1,76 @@ +/* + * This file is generated by jOOQ. + */ +package edu.uci.ics.texera.dao.jooq.generated.tables.daos; + + +import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetViewCount; +import edu.uci.ics.texera.dao.jooq.generated.tables.records.DatasetViewCountRecord; + +import java.util.List; + +import org.jooq.Configuration; +import org.jooq.impl.DAOImpl; +import org.jooq.types.UInteger; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class DatasetViewCountDao extends DAOImpl { + + /** + * Create a new DatasetViewCountDao without any configuration + */ + public DatasetViewCountDao() { + super(DatasetViewCount.DATASET_VIEW_COUNT, edu.uci.ics.texera.dao.jooq.generated.tables.pojos.DatasetViewCount.class); + } + + /** + * Create a new DatasetViewCountDao with an attached configuration + */ + public DatasetViewCountDao(Configuration configuration) { + super(DatasetViewCount.DATASET_VIEW_COUNT, edu.uci.ics.texera.dao.jooq.generated.tables.pojos.DatasetViewCount.class, configuration); + } + + @Override + public UInteger getId(edu.uci.ics.texera.dao.jooq.generated.tables.pojos.DatasetViewCount object) { + return object.getDid(); + } + + /** + * Fetch records that have did BETWEEN lowerInclusive AND upperInclusive + */ + public List fetchRangeOfDid(UInteger lowerInclusive, UInteger upperInclusive) { + return fetchRange(DatasetViewCount.DATASET_VIEW_COUNT.DID, lowerInclusive, upperInclusive); + } + + /** + * Fetch records that have did IN (values) + */ + public List fetchByDid(UInteger... values) { + return fetch(DatasetViewCount.DATASET_VIEW_COUNT.DID, values); + } + + /** + * Fetch a unique record that has did = value + */ + public edu.uci.ics.texera.dao.jooq.generated.tables.pojos.DatasetViewCount fetchOneByDid(UInteger value) { + return fetchOne(DatasetViewCount.DATASET_VIEW_COUNT.DID, value); + } + + /** + * Fetch records that have view_count BETWEEN lowerInclusive AND upperInclusive + */ + public List fetchRangeOfViewCount(UInteger lowerInclusive, UInteger upperInclusive) { + return fetchRange(DatasetViewCount.DATASET_VIEW_COUNT.VIEW_COUNT, lowerInclusive, upperInclusive); + } + + /** + * Fetch records that have view_count IN (values) + */ + public List fetchByViewCount(UInteger... values) { + return fetch(DatasetViewCount.DATASET_VIEW_COUNT.VIEW_COUNT, values); + } +} diff --git a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/interfaces/IDatasetUserLikes.java b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/interfaces/IDatasetUserLikes.java new file mode 100644 index 0000000000..b9bf758280 --- /dev/null +++ b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/interfaces/IDatasetUserLikes.java @@ -0,0 +1,51 @@ +/* + * This file is generated by jOOQ. + */ +package edu.uci.ics.texera.dao.jooq.generated.tables.interfaces; + + +import java.io.Serializable; + +import org.jooq.types.UInteger; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public interface IDatasetUserLikes extends Serializable { + + /** + * Setter for texera_db.dataset_user_likes.uid. + */ + public void setUid(UInteger value); + + /** + * Getter for texera_db.dataset_user_likes.uid. + */ + public UInteger getUid(); + + /** + * Setter for texera_db.dataset_user_likes.did. + */ + public void setDid(UInteger value); + + /** + * Getter for texera_db.dataset_user_likes.did. + */ + public UInteger getDid(); + + // ------------------------------------------------------------------------- + // FROM and INTO + // ------------------------------------------------------------------------- + + /** + * Load data from another generated Record/POJO implementing the common interface IDatasetUserLikes + */ + public void from(edu.uci.ics.texera.dao.jooq.generated.tables.interfaces.IDatasetUserLikes from); + + /** + * Copy data into another generated Record/POJO implementing the common interface IDatasetUserLikes + */ + public E into(E into); +} diff --git a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/interfaces/IDatasetViewCount.java b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/interfaces/IDatasetViewCount.java new file mode 100644 index 0000000000..0894f9c76f --- /dev/null +++ b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/interfaces/IDatasetViewCount.java @@ -0,0 +1,51 @@ +/* + * This file is generated by jOOQ. + */ +package edu.uci.ics.texera.dao.jooq.generated.tables.interfaces; + + +import java.io.Serializable; + +import org.jooq.types.UInteger; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public interface IDatasetViewCount extends Serializable { + + /** + * Setter for texera_db.dataset_view_count.did. + */ + public void setDid(UInteger value); + + /** + * Getter for texera_db.dataset_view_count.did. + */ + public UInteger getDid(); + + /** + * Setter for texera_db.dataset_view_count.view_count. + */ + public void setViewCount(UInteger value); + + /** + * Getter for texera_db.dataset_view_count.view_count. + */ + public UInteger getViewCount(); + + // ------------------------------------------------------------------------- + // FROM and INTO + // ------------------------------------------------------------------------- + + /** + * Load data from another generated Record/POJO implementing the common interface IDatasetViewCount + */ + public void from(edu.uci.ics.texera.dao.jooq.generated.tables.interfaces.IDatasetViewCount from); + + /** + * Copy data into another generated Record/POJO implementing the common interface IDatasetViewCount + */ + public E into(E into); +} diff --git a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/pojos/DatasetUserLikes.java b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/pojos/DatasetUserLikes.java new file mode 100644 index 0000000000..7e2829cd8b --- /dev/null +++ b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/pojos/DatasetUserLikes.java @@ -0,0 +1,84 @@ +/* + * This file is generated by jOOQ. + */ +package edu.uci.ics.texera.dao.jooq.generated.tables.pojos; + + +import edu.uci.ics.texera.dao.jooq.generated.tables.interfaces.IDatasetUserLikes; + +import org.jooq.types.UInteger; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class DatasetUserLikes implements IDatasetUserLikes { + + private static final long serialVersionUID = -230105384; + + private UInteger uid; + private UInteger did; + + public DatasetUserLikes() {} + + public DatasetUserLikes(IDatasetUserLikes value) { + this.uid = value.getUid(); + this.did = value.getDid(); + } + + public DatasetUserLikes( + UInteger uid, + UInteger did + ) { + this.uid = uid; + this.did = did; + } + + @Override + public UInteger getUid() { + return this.uid; + } + + @Override + public void setUid(UInteger uid) { + this.uid = uid; + } + + @Override + public UInteger getDid() { + return this.did; + } + + @Override + public void setDid(UInteger did) { + this.did = did; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("DatasetUserLikes ("); + + sb.append(uid); + sb.append(", ").append(did); + + sb.append(")"); + return sb.toString(); + } + + // ------------------------------------------------------------------------- + // FROM and INTO + // ------------------------------------------------------------------------- + + @Override + public void from(IDatasetUserLikes from) { + setUid(from.getUid()); + setDid(from.getDid()); + } + + @Override + public E into(E into) { + into.from(this); + return into; + } +} diff --git a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/pojos/DatasetViewCount.java b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/pojos/DatasetViewCount.java new file mode 100644 index 0000000000..37f2665a4e --- /dev/null +++ b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/pojos/DatasetViewCount.java @@ -0,0 +1,84 @@ +/* + * This file is generated by jOOQ. + */ +package edu.uci.ics.texera.dao.jooq.generated.tables.pojos; + + +import edu.uci.ics.texera.dao.jooq.generated.tables.interfaces.IDatasetViewCount; + +import org.jooq.types.UInteger; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class DatasetViewCount implements IDatasetViewCount { + + private static final long serialVersionUID = 584045490; + + private UInteger did; + private UInteger viewCount; + + public DatasetViewCount() {} + + public DatasetViewCount(IDatasetViewCount value) { + this.did = value.getDid(); + this.viewCount = value.getViewCount(); + } + + public DatasetViewCount( + UInteger did, + UInteger viewCount + ) { + this.did = did; + this.viewCount = viewCount; + } + + @Override + public UInteger getDid() { + return this.did; + } + + @Override + public void setDid(UInteger did) { + this.did = did; + } + + @Override + public UInteger getViewCount() { + return this.viewCount; + } + + @Override + public void setViewCount(UInteger viewCount) { + this.viewCount = viewCount; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("DatasetViewCount ("); + + sb.append(did); + sb.append(", ").append(viewCount); + + sb.append(")"); + return sb.toString(); + } + + // ------------------------------------------------------------------------- + // FROM and INTO + // ------------------------------------------------------------------------- + + @Override + public void from(IDatasetViewCount from) { + setDid(from.getDid()); + setViewCount(from.getViewCount()); + } + + @Override + public E into(E into) { + into.from(this); + return into; + } +} diff --git a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/records/DatasetUserLikesRecord.java b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/records/DatasetUserLikesRecord.java new file mode 100644 index 0000000000..1e006ad00c --- /dev/null +++ b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/records/DatasetUserLikesRecord.java @@ -0,0 +1,165 @@ +/* + * This file is generated by jOOQ. + */ +package edu.uci.ics.texera.dao.jooq.generated.tables.records; + + +import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetUserLikes; +import edu.uci.ics.texera.dao.jooq.generated.tables.interfaces.IDatasetUserLikes; + +import org.jooq.Field; +import org.jooq.Record2; +import org.jooq.Row2; +import org.jooq.impl.UpdatableRecordImpl; +import org.jooq.types.UInteger; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class DatasetUserLikesRecord extends UpdatableRecordImpl implements Record2, IDatasetUserLikes { + + private static final long serialVersionUID = -612498918; + + /** + * Setter for texera_db.dataset_user_likes.uid. + */ + @Override + public void setUid(UInteger value) { + set(0, value); + } + + /** + * Getter for texera_db.dataset_user_likes.uid. + */ + @Override + public UInteger getUid() { + return (UInteger) get(0); + } + + /** + * Setter for texera_db.dataset_user_likes.did. + */ + @Override + public void setDid(UInteger value) { + set(1, value); + } + + /** + * Getter for texera_db.dataset_user_likes.did. + */ + @Override + public UInteger getDid() { + return (UInteger) get(1); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + @Override + public Record2 key() { + return (Record2) super.key(); + } + + // ------------------------------------------------------------------------- + // Record2 type implementation + // ------------------------------------------------------------------------- + + @Override + public Row2 fieldsRow() { + return (Row2) super.fieldsRow(); + } + + @Override + public Row2 valuesRow() { + return (Row2) super.valuesRow(); + } + + @Override + public Field field1() { + return DatasetUserLikes.DATASET_USER_LIKES.UID; + } + + @Override + public Field field2() { + return DatasetUserLikes.DATASET_USER_LIKES.DID; + } + + @Override + public UInteger component1() { + return getUid(); + } + + @Override + public UInteger component2() { + return getDid(); + } + + @Override + public UInteger value1() { + return getUid(); + } + + @Override + public UInteger value2() { + return getDid(); + } + + @Override + public DatasetUserLikesRecord value1(UInteger value) { + setUid(value); + return this; + } + + @Override + public DatasetUserLikesRecord value2(UInteger value) { + setDid(value); + return this; + } + + @Override + public DatasetUserLikesRecord values(UInteger value1, UInteger value2) { + value1(value1); + value2(value2); + return this; + } + + // ------------------------------------------------------------------------- + // FROM and INTO + // ------------------------------------------------------------------------- + + @Override + public void from(IDatasetUserLikes from) { + setUid(from.getUid()); + setDid(from.getDid()); + } + + @Override + public E into(E into) { + into.from(this); + return into; + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached DatasetUserLikesRecord + */ + public DatasetUserLikesRecord() { + super(DatasetUserLikes.DATASET_USER_LIKES); + } + + /** + * Create a detached, initialised DatasetUserLikesRecord + */ + public DatasetUserLikesRecord(UInteger uid, UInteger did) { + super(DatasetUserLikes.DATASET_USER_LIKES); + + set(0, uid); + set(1, did); + } +} diff --git a/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/records/DatasetViewCountRecord.java b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/records/DatasetViewCountRecord.java new file mode 100644 index 0000000000..a8234b6089 --- /dev/null +++ b/core/dao/src/main/scala/edu/uci/ics/texera/dao/jooq/generated/tables/records/DatasetViewCountRecord.java @@ -0,0 +1,166 @@ +/* + * This file is generated by jOOQ. + */ +package edu.uci.ics.texera.dao.jooq.generated.tables.records; + + +import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetViewCount; +import edu.uci.ics.texera.dao.jooq.generated.tables.interfaces.IDatasetViewCount; + +import org.jooq.Field; +import org.jooq.Record1; +import org.jooq.Record2; +import org.jooq.Row2; +import org.jooq.impl.UpdatableRecordImpl; +import org.jooq.types.UInteger; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class DatasetViewCountRecord extends UpdatableRecordImpl implements Record2, IDatasetViewCount { + + private static final long serialVersionUID = -1848694937; + + /** + * Setter for texera_db.dataset_view_count.did. + */ + @Override + public void setDid(UInteger value) { + set(0, value); + } + + /** + * Getter for texera_db.dataset_view_count.did. + */ + @Override + public UInteger getDid() { + return (UInteger) get(0); + } + + /** + * Setter for texera_db.dataset_view_count.view_count. + */ + @Override + public void setViewCount(UInteger value) { + set(1, value); + } + + /** + * Getter for texera_db.dataset_view_count.view_count. + */ + @Override + public UInteger getViewCount() { + return (UInteger) get(1); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + @Override + public Record1 key() { + return (Record1) super.key(); + } + + // ------------------------------------------------------------------------- + // Record2 type implementation + // ------------------------------------------------------------------------- + + @Override + public Row2 fieldsRow() { + return (Row2) super.fieldsRow(); + } + + @Override + public Row2 valuesRow() { + return (Row2) super.valuesRow(); + } + + @Override + public Field field1() { + return DatasetViewCount.DATASET_VIEW_COUNT.DID; + } + + @Override + public Field field2() { + return DatasetViewCount.DATASET_VIEW_COUNT.VIEW_COUNT; + } + + @Override + public UInteger component1() { + return getDid(); + } + + @Override + public UInteger component2() { + return getViewCount(); + } + + @Override + public UInteger value1() { + return getDid(); + } + + @Override + public UInteger value2() { + return getViewCount(); + } + + @Override + public DatasetViewCountRecord value1(UInteger value) { + setDid(value); + return this; + } + + @Override + public DatasetViewCountRecord value2(UInteger value) { + setViewCount(value); + return this; + } + + @Override + public DatasetViewCountRecord values(UInteger value1, UInteger value2) { + value1(value1); + value2(value2); + return this; + } + + // ------------------------------------------------------------------------- + // FROM and INTO + // ------------------------------------------------------------------------- + + @Override + public void from(IDatasetViewCount from) { + setDid(from.getDid()); + setViewCount(from.getViewCount()); + } + + @Override + public E into(E into) { + into.from(this); + return into; + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached DatasetViewCountRecord + */ + public DatasetViewCountRecord() { + super(DatasetViewCount.DATASET_VIEW_COUNT); + } + + /** + * Create a detached, initialised DatasetViewCountRecord + */ + public DatasetViewCountRecord(UInteger did, UInteger viewCount) { + super(DatasetViewCount.DATASET_VIEW_COUNT); + + set(0, did); + set(1, viewCount); + } +} From 0a496465f7953689dba8d83271b3b4110fbaf0a5 Mon Sep 17 00:00:00 2001 From: gspikehalo <2318002579@qq.com> Date: Sun, 16 Feb 2025 18:13:30 -0800 Subject: [PATCH 2/8] Restore the initial modifications. --- .../resource/dashboard/hub/EntityTables.scala | 20 ++++ .../user/list-item/list-item.component.html | 23 +++-- .../user/list-item/list-item.component.ts | 57 ++++++----- .../dataset-detail.component.html | 32 ++++++- .../dataset-detail.component.scss | 16 ++++ .../dataset-detail.component.ts | 96 ++++++++++++++++++- core/scripts/sql/texera_ddl.sql | 21 ++++ core/scripts/sql/update/22.sql | 20 ++++ 8 files changed, 249 insertions(+), 36 deletions(-) create mode 100644 core/scripts/sql/update/22.sql diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/EntityTables.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/EntityTables.scala index fe5ddf0d95..9736294246 100644 --- a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/EntityTables.scala +++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/EntityTables.scala @@ -2,6 +2,8 @@ package edu.uci.ics.texera.web.resource.dashboard.hub import edu.uci.ics.texera.dao.jooq.generated.tables.records.{ DatasetRecord, + DatasetUserLikesRecord, + DatasetViewCountRecord, WorkflowRecord, WorkflowUserClonesRecord, WorkflowUserLikesRecord, @@ -65,9 +67,18 @@ object EntityTables { override val idColumn: TableField[WorkflowUserLikesRecord, UInteger] = WORKFLOW_USER_LIKES.WID } + case object DatasetLikeTable extends LikeTable { + override type R = DatasetUserLikesRecord + override val table: Table[DatasetUserLikesRecord] = DATASET_USER_LIKES + override val uidColumn: TableField[DatasetUserLikesRecord, UInteger] = + DATASET_USER_LIKES.UID + override val idColumn: TableField[DatasetUserLikesRecord, UInteger] = DATASET_USER_LIKES.DID + } + def apply(entityType: String): LikeTable = entityType match { case "workflow" => WorkflowLikeTable + case "dataset" => DatasetLikeTable case _ => throw new IllegalArgumentException(s"Unsupported entity type: $entityType for like") } @@ -111,9 +122,18 @@ object EntityTables { WORKFLOW_VIEW_COUNT.VIEW_COUNT } + case object DatasetViewCountTable extends ViewCountTable { + override type R = DatasetViewCountRecord + override val table: Table[DatasetViewCountRecord] = DATASET_VIEW_COUNT + override val idColumn: TableField[DatasetViewCountRecord, UInteger] = DATASET_VIEW_COUNT.DID + override val viewCountColumn: TableField[DatasetViewCountRecord, UInteger] = + DATASET_VIEW_COUNT.VIEW_COUNT + } + def apply(entityType: String): ViewCountTable = entityType match { case "workflow" => WorkflowViewCountTable + case "dataset" => DatasetViewCountTable case _ => throw new IllegalArgumentException(s"Unsupported entity type: $entityType for view count") } diff --git a/core/gui/src/app/dashboard/component/user/list-item/list-item.component.html b/core/gui/src/app/dashboard/component/user/list-item/list-item.component.html index 5239ede799..d3c9206e30 100644 --- a/core/gui/src/app/dashboard/component/user/list-item/list-item.component.html +++ b/core/gui/src/app/dashboard/component/user/list-item/list-item.component.html @@ -114,13 +114,24 @@
- +
+ Size: {{ formatSize(entry.size) }} +
+
+ +
+
{{ formatCount(viewCount) }}
views - - Size: {{ formatSize(entry.size) }} +
+
diff --git a/core/gui/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.scss b/core/gui/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.scss index 1c7eed801e..582e066273 100644 --- a/core/gui/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.scss +++ b/core/gui/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.scss @@ -123,3 +123,19 @@ nz-select { .nz-tag { font-size: 12px; } + +.workflow-panel { + display: flex; + align-items: center; + gap: 10px; +} + +.like-button { + width: 70px; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +.liked { + color: red; +} diff --git a/core/gui/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.ts b/core/gui/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.ts index 1ff6d80e8e..81b192b820 100644 --- a/core/gui/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.ts +++ b/core/gui/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.ts @@ -5,12 +5,16 @@ import { DatasetService } from "../../../../service/user/dataset/dataset.service import { NzResizeEvent } from "ng-zorro-antd/resizable"; import { DatasetFileNode, getFullPathFromDatasetFileNode } from "../../../../../common/type/datasetVersionFileTree"; import { DatasetVersion } from "../../../../../common/type/dataset"; -import { switchMap } from "rxjs/operators"; +import { switchMap, throttleTime } from "rxjs/operators"; import { NotificationService } from "../../../../../common/service/notification/notification.service"; import { DownloadService } from "../../../../service/user/download/download.service"; import { formatSize } from "src/app/common/util/size-formatter.util"; import { DASHBOARD_USER_DATASET } from "../../../../../app-routing.constant"; import { UserService } from "../../../../../common/service/user/user.service"; +import { isDefined } from "../../../../../common/util/predicate"; +import { HubService } from "../../../../../hub/service/hub.service"; + +export const THROTTLE_TIME_MS = 1000; @UntilDestroy() @Component({ @@ -41,18 +45,26 @@ export class DatasetDetailComponent implements OnInit { public versionCreatorBaseVersion: DatasetVersion | undefined; public isLogin: boolean = this.userService.isLogin(); + public isLiked: boolean = false; + public likeCount: number = 0; + public currentUid: number | undefined; + public viewCount: number = 0; + public displayPreciseViewCount = false; + constructor( private route: ActivatedRoute, private router: Router, private datasetService: DatasetService, private notificationService: NotificationService, private downloadService: DownloadService, - private userService: UserService + private userService: UserService, + private hubService: HubService ) { this.userService .userChanged() .pipe(untilDestroyed(this)) .subscribe(() => { + this.currentUid = this.userService.getCurrentUser()?.uid; this.isLogin = this.userService.isLogin(); }); } @@ -87,6 +99,36 @@ export class DatasetDetailComponent implements OnInit { untilDestroyed(this) ) .subscribe(); + + if (!isDefined(this.did)) { + return; + } + + this.hubService + .getLikeCount(this.did, "dataset") + .pipe(untilDestroyed(this)) + .subscribe(count => { + this.likeCount = count; + }); + + this.hubService + .postView(this.did, this.currentUid ? this.currentUid : 0, "dataset") + .pipe(throttleTime(THROTTLE_TIME_MS)) + .pipe(untilDestroyed(this)) + .subscribe(count => { + this.viewCount = count; + }); + + if (!isDefined(this.currentUid)) { + return; + } + + this.hubService + .isLiked(this.did, this.currentUid, "dataset") + .pipe(untilDestroyed(this)) + .subscribe((isLiked: boolean) => { + this.isLiked = isLiked; + }); } renderDatasetViewSider() { @@ -252,4 +294,54 @@ export class DatasetDetailComponent implements OnInit { // alias for formatSize formatSize = formatSize; + + formatCount(count: number): string { + if (count >= 1000) { + return (count / 1000).toFixed(1) + "k"; + } + return count.toString(); + } + + toggleLike(): void { + const userId = this.currentUid; + if (!isDefined(userId) || !isDefined(this.did)) { + return; + } + + if (this.isLiked) { + this.hubService + .postUnlike(this.did, userId, "dataset") + .pipe(untilDestroyed(this)) + .subscribe((success: boolean) => { + if (success) { + this.isLiked = false; + this.hubService + .getLikeCount(this.did!, "dataset") + .pipe(untilDestroyed(this)) + .subscribe((count: number) => { + this.likeCount = count; + }); + } + }); + } else { + this.hubService + .postLike(this.did, userId, "dataset") + .pipe(untilDestroyed(this)) + .subscribe((success: boolean) => { + if (success) { + this.isLiked = true; + this.hubService + .getLikeCount(this.did!, "dataset") + .pipe(untilDestroyed(this)) + .subscribe((count: number) => { + this.likeCount = count; + }); + } + }); + } + } + + changeViewDisplayStyle() { + this.displayPreciseViewCount = !this.displayPreciseViewCount; + } } diff --git a/core/scripts/sql/texera_ddl.sql b/core/scripts/sql/texera_ddl.sql index b6724e0eb9..16b33a3ae1 100644 --- a/core/scripts/sql/texera_ddl.sql +++ b/core/scripts/sql/texera_ddl.sql @@ -15,6 +15,10 @@ DROP TABLE IF EXISTS `workflow_executions`; DROP TABLE IF EXISTS `dataset`; DROP TABLE IF EXISTS `dataset_user_access`; DROP TABLE IF EXISTS `dataset_version`; +DROP TABLE IF EXISTS operator_executions; +DROP TABLE IF EXISTS operator_runtime_statistics; +DROP TABLE IF EXISTS `dataset_user_likes`; +DROP TABLE IF EXISTS dataset_view_count; SET PERSIST time_zone = '+00:00'; -- this line is mandatory SET PERSIST sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); @@ -262,4 +266,21 @@ CREATE TABLE IF NOT EXISTS user_activity ( `ip` VARCHAR(15) DEFAULT NULL, `activate` VARCHAR(10) NOT NULL, `activity_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP + + ) ENGINE = INNODB; + +CREATE TABLE IF NOT EXISTS dataset_user_likes +( + `uid` INT UNSIGNED NOT NULL, + `did` INT UNSIGNED NOT NULL, + PRIMARY KEY (`uid`, `did`), + FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON DELETE CASCADE, + FOREIGN KEY (`did`) REFERENCES `dataset` (`did`) ON DELETE CASCADE + ) ENGINE = INNODB; + +CREATE TABLE IF NOT EXISTS `dataset_view_count` ( + `did` INT UNSIGNED NOT NULL, + `view_count` INT UNSIGNED NOT NULL DEFAULT 0, + PRIMARY KEY (`did`), + FOREIGN KEY (`did`) REFERENCES `dataset` (`did`) ON DELETE CASCADE ) ENGINE = INNODB; \ No newline at end of file diff --git a/core/scripts/sql/update/22.sql b/core/scripts/sql/update/22.sql new file mode 100644 index 0000000000..bda70bc700 --- /dev/null +++ b/core/scripts/sql/update/22.sql @@ -0,0 +1,20 @@ +USE texera_db; + +DROP TABLE IF EXISTS dataset_user_likes; +DROP TABLE IF EXISTS dataset_view_count; + +CREATE TABLE IF NOT EXISTS dataset_user_likes +( + `uid` INT UNSIGNED NOT NULL, + `did` INT UNSIGNED NOT NULL, + PRIMARY KEY (`uid`, `did`), + FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON DELETE CASCADE, + FOREIGN KEY (`did`) REFERENCES `dataset` (`did`) ON DELETE CASCADE + ) ENGINE = INNODB; + +CREATE TABLE IF NOT EXISTS `dataset_view_count` ( + `did` INT UNSIGNED NOT NULL, + `view_count` INT UNSIGNED NOT NULL DEFAULT 0, + PRIMARY KEY (`did`), + FOREIGN KEY (`did`) REFERENCES `dataset` (`did`) ON DELETE CASCADE + ) ENGINE = INNODB; \ No newline at end of file From 4523ef4c1fa12917fa9bc4c6c8bb9e4e53ce374a Mon Sep 17 00:00:00 2001 From: gspikehalo <2318002579@qq.com> Date: Sun, 16 Feb 2025 18:15:33 -0800 Subject: [PATCH 3/8] resolve comments --- .../user-dataset-explorer/dataset-detail.component.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/gui/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.scss b/core/gui/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.scss index 582e066273..7a57e8f597 100644 --- a/core/gui/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.scss +++ b/core/gui/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.scss @@ -125,12 +125,12 @@ nz-select { } .workflow-panel { - display: flex; align-items: center; gap: 10px; } .like-button { + margin-left: 15px; width: 70px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); From 3ad29065ad186822f116d8e9374f7b9f0d3abb31 Mon Sep 17 00:00:00 2001 From: gspikehalo <2318002579@qq.com> Date: Mon, 17 Feb 2025 21:47:15 -0800 Subject: [PATCH 4/8] refactor current landing page api --- .../resource/dashboard/hub/EntityTables.scala | 3 + .../resource/dashboard/hub/HubResource.scala | 137 +++++++----------- .../user/workflow/WorkflowResource.scala | 96 ++++++------ .../landing-page/landing-page.component.ts | 131 +++++++++-------- core/gui/src/app/hub/service/hub.service.ts | 15 +- 5 files changed, 186 insertions(+), 196 deletions(-) diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/EntityTables.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/EntityTables.scala index 9736294246..d09c445c52 100644 --- a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/EntityTables.scala +++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/EntityTables.scala @@ -19,6 +19,7 @@ object EntityTables { type R <: Record val table: Table[R] val isPublicColumn: TableField[R, java.lang.Byte] + val idColumn: TableField[R, UInteger] } object BaseEntityTable { @@ -26,12 +27,14 @@ object EntityTables { override type R = WorkflowRecord override val table: Table[WorkflowRecord] = WORKFLOW override val isPublicColumn: TableField[WorkflowRecord, java.lang.Byte] = WORKFLOW.IS_PUBLIC + override val idColumn: TableField[WorkflowRecord, UInteger] = WORKFLOW.WID } case object DatasetTable extends BaseEntityTable { override type R = DatasetRecord override val table: Table[DatasetRecord] = DATASET override val isPublicColumn: TableField[DatasetRecord, java.lang.Byte] = DATASET.IS_PUBLIC + override val idColumn: TableField[DatasetRecord, UInteger] = DATASET.DID } def apply(entityType: String): BaseEntityTable = { diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/HubResource.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/HubResource.scala index ad95146902..2a967bbfde 100644 --- a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/HubResource.scala +++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/HubResource.scala @@ -3,28 +3,19 @@ package edu.uci.ics.texera.web.resource.dashboard.hub import edu.uci.ics.amber.core.storage.StorageConfig import edu.uci.ics.texera.dao.SqlServer import edu.uci.ics.texera.dao.jooq.generated.Tables._ -import edu.uci.ics.texera.dao.jooq.generated.tables.pojos.Workflow -import HubResource.{ - fetchDashboardWorkflowsByWids, - getUserLCCount, - isLikedHelper, - recordLikeActivity, - recordUserActivity, - userRequest, - validateEntityType -} -import edu.uci.ics.texera.web.resource.dashboard.user.workflow.WorkflowResource.DashboardWorkflow +import HubResource.{fetchDashboardWorkflowsByWids, getUserLCCount, isLikedHelper, recordLikeActivity, recordUserActivity, userRequest, validateEntityType} +import edu.uci.ics.texera.web.resource.dashboard.user.workflow.WorkflowResource.{DashboardWorkflow, baseWorkflowSelect, mapWorkflowEntries} import org.jooq.impl.DSL import org.jooq.types.UInteger import java.util -import java.util.Collections import java.util.regex.Pattern import javax.servlet.http.HttpServletRequest import javax.ws.rs._ import javax.ws.rs.core.{Context, MediaType} import scala.jdk.CollectionConverters._ import EntityTables._ +import edu.uci.ics.texera.web.resource.dashboard.DashboardResource.DashboardClickableFileEntry object HubResource { case class userRequest(entityId: UInteger, userId: UInteger, entityType: String) @@ -228,52 +219,17 @@ object HubResource { .fetchOne(0, classOf[Int]) } - // todo: refactor api related to landing page - def fetchDashboardWorkflowsByWids(wids: Seq[UInteger]): util.List[DashboardWorkflow] = { - if (wids.nonEmpty) { - context - .select( - WORKFLOW.NAME, - WORKFLOW.DESCRIPTION, - WORKFLOW.WID, - WORKFLOW.CREATION_TIME, - WORKFLOW.LAST_MODIFIED_TIME, - USER.NAME.as("ownerName"), - WORKFLOW_OF_USER.UID.as("ownerId") - ) - .from(WORKFLOW) - .join(WORKFLOW_OF_USER) - .on(WORKFLOW.WID.eq(WORKFLOW_OF_USER.WID)) - .join(USER) - .on(WORKFLOW_OF_USER.UID.eq(USER.UID)) - .where(WORKFLOW.WID.in(wids: _*)) - .fetch() - .asScala - .map(record => { - val workflow = new Workflow( - record.get(WORKFLOW.NAME), - record.get(WORKFLOW.DESCRIPTION), - record.get(WORKFLOW.WID), - null, - record.get(WORKFLOW.CREATION_TIME), - record.get(WORKFLOW.LAST_MODIFIED_TIME), - null - ) - - DashboardWorkflow( - isOwner = false, - accessLevel = "", - ownerName = record.get("ownerName", classOf[String]), - workflow = workflow, - projectIDs = List(), - ownerId = record.get("ownerId", classOf[UInteger]) - ) - }) - .toList - .asJava - } else { - Collections.emptyList[DashboardWorkflow]() + def fetchDashboardWorkflowsByWids(wids: Seq[UInteger], uid: UInteger): List[DashboardWorkflow] = { + if (wids.isEmpty) { + return List.empty[DashboardWorkflow] } + + val records = baseWorkflowSelect() + .where(WORKFLOW.WID.in(wids: _*)) + .groupBy(WORKFLOW.WID, WORKFLOW_OF_USER.UID) + .fetch() + + mapWorkflowEntries( records, uid) } } @@ -411,42 +367,51 @@ class HubResource { } @GET - @Path("/topLovedWorkflows") + @Path("/getTops") @Produces(Array(MediaType.APPLICATION_JSON)) - def getTopLovedWorkflows: util.List[DashboardWorkflow] = { - val topLovedWorkflowsWids = context - .select(WORKFLOW_USER_LIKES.WID) - .from(WORKFLOW_USER_LIKES) - .join(WORKFLOW) - .on(WORKFLOW_USER_LIKES.WID.eq(WORKFLOW.WID)) - .where(WORKFLOW.IS_PUBLIC.eq(1.toByte)) - .groupBy(WORKFLOW_USER_LIKES.WID) - .orderBy(DSL.count(WORKFLOW_USER_LIKES.WID).desc()) - .limit(8) - .fetchInto(classOf[UInteger]) - .asScala - .toSeq + def getTops(@QueryParam("entityType") entityType: String, @QueryParam("actionType") actionType: String, @QueryParam("uid") uid: Integer): util.List[DashboardClickableFileEntry] = { + validateEntityType(entityType) - fetchDashboardWorkflowsByWids(topLovedWorkflowsWids) - } + val baseTable = BaseEntityTable(entityType) + val entityTables = actionType match { + case "like" => LikeTable(entityType) + case "clone" => CloneTable(entityType) + case _ => throw new IllegalArgumentException(s"Invalid action type: $actionType") + } - @GET - @Path("/topClonedWorkflows") - @Produces(Array(MediaType.APPLICATION_JSON)) - def getTopClonedWorkflows: util.List[DashboardWorkflow] = { - val topClonedWorkflowsWids = context - .select(WORKFLOW_USER_CLONES.WID) - .from(WORKFLOW_USER_CLONES) - .join(WORKFLOW) - .on(WORKFLOW_USER_CLONES.WID.eq(WORKFLOW.WID)) - .where(WORKFLOW.IS_PUBLIC.eq(1.toByte)) - .groupBy(WORKFLOW_USER_CLONES.WID) - .orderBy(DSL.count(WORKFLOW_USER_CLONES.WID).desc()) + val (table, idColumn) = (entityTables.table, entityTables.idColumn) + val (isPublicColumn, baseIdColumn) = (baseTable.isPublicColumn, baseTable.idColumn) + + val topEntityIds = context + .select(idColumn) + .from(table) + .join(baseTable.table) + .on(idColumn.eq(baseIdColumn)) + .where(isPublicColumn.eq(1.toByte)) + .groupBy(idColumn) + .orderBy(DSL.count(idColumn).desc()) .limit(8) .fetchInto(classOf[UInteger]) .asScala .toSeq - fetchDashboardWorkflowsByWids(topClonedWorkflowsWids) + val currentUid: UInteger = if (uid == null || uid == -1) null else UInteger.valueOf(uid) + + val clickableFileEntries = + if (entityType == "workflow") { + val workflows = fetchDashboardWorkflowsByWids(topEntityIds, currentUid) + workflows.map { w => + DashboardClickableFileEntry( + resourceType = "workflow", + workflow = Some(w), + project = None, + dataset = None + ) + } + } else { + Seq.empty[DashboardClickableFileEntry] + } + + clickableFileEntries.toList.asJava } } diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala index 687dde8cb9..6e7f417ca8 100644 --- a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala +++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala @@ -8,20 +8,16 @@ import edu.uci.ics.texera.dao.SqlServer import edu.uci.ics.texera.web.auth.SessionUser import edu.uci.ics.texera.dao.jooq.generated.Tables._ import edu.uci.ics.texera.dao.jooq.generated.enums.WorkflowUserAccessPrivilege -import edu.uci.ics.texera.dao.jooq.generated.tables.daos.{ - WorkflowDao, - WorkflowOfProjectDao, - WorkflowOfUserDao, - WorkflowUserAccessDao -} +import edu.uci.ics.texera.dao.jooq.generated.tables.daos.{WorkflowDao, WorkflowOfProjectDao, WorkflowOfUserDao, WorkflowUserAccessDao} import edu.uci.ics.texera.dao.jooq.generated.tables.pojos._ import edu.uci.ics.texera.web.resource.dashboard.hub.HubResource.recordCloneActivity import edu.uci.ics.texera.web.resource.dashboard.user.workflow.WorkflowAccessResource.hasReadAccess import edu.uci.ics.texera.web.resource.dashboard.user.workflow.WorkflowResource._ import io.dropwizard.auth.Auth -import org.jooq.Condition +import org.jooq.{Condition, Record9, SelectOnConditionStep} import org.jooq.impl.DSL.{groupConcatDistinct, noCondition} import org.jooq.types.UInteger +import org.jooq.{Record, Result} import java.sql.Timestamp import java.util @@ -160,6 +156,50 @@ object WorkflowResource { updatedContent.replace(oldId, newId) } } + + def baseWorkflowSelect(): SelectOnConditionStep[Record9[UInteger, String, String, Timestamp, Timestamp, WorkflowUserAccessPrivilege, UInteger, String, String]] = { + context + .select( + WORKFLOW.WID, + WORKFLOW.NAME, + WORKFLOW.DESCRIPTION, + WORKFLOW.CREATION_TIME, + WORKFLOW.LAST_MODIFIED_TIME, + WORKFLOW_USER_ACCESS.PRIVILEGE, + WORKFLOW_OF_USER.UID, + USER.NAME, + groupConcatDistinct(WORKFLOW_OF_PROJECT.PID).as("projects") + ) + .from(WORKFLOW) + .leftJoin(WORKFLOW_USER_ACCESS).on(WORKFLOW_USER_ACCESS.WID.eq(WORKFLOW.WID)) + .leftJoin(WORKFLOW_OF_USER).on(WORKFLOW_OF_USER.WID.eq(WORKFLOW.WID)) + .leftJoin(USER).on(USER.UID.eq(WORKFLOW_OF_USER.UID)) + .leftJoin(WORKFLOW_OF_PROJECT).on(WORKFLOW.WID.eq(WORKFLOW_OF_PROJECT.WID)) + } + + def mapWorkflowEntries(workflowEntries: Result[Record9[UInteger, String, String, Timestamp, Timestamp, WorkflowUserAccessPrivilege, UInteger, String, String]], uid: UInteger ): List[DashboardWorkflow] = { + workflowEntries + .map(workflowRecord => + DashboardWorkflow( + if (uid != null) + workflowRecord.into(WORKFLOW_OF_USER).getUid.eq(uid) + else false, + workflowRecord + .into(WORKFLOW_USER_ACCESS) + .into(classOf[WorkflowUserAccess]) + .getPrivilege + .toString, + workflowRecord.into(USER).getName, + workflowRecord.into(WORKFLOW).into(classOf[Workflow]), + if (workflowRecord.component9() == null) List[UInteger]() + else + workflowRecord.component9().split(',').map(number => UInteger.valueOf(number)).toList, + workflowRecord.into(WORKFLOW_OF_USER).getUid + ) + ) + .asScala + .toList + } } @Produces(Array(MediaType.APPLICATION_JSON)) @@ -267,49 +307,11 @@ class WorkflowResource extends LazyLogging { @Auth sessionUser: SessionUser ): List[DashboardWorkflow] = { val user = sessionUser.getUser - val workflowEntries = context - .select( - WORKFLOW.WID, - WORKFLOW.NAME, - WORKFLOW.DESCRIPTION, - WORKFLOW.CREATION_TIME, - WORKFLOW.LAST_MODIFIED_TIME, - WORKFLOW_USER_ACCESS.PRIVILEGE, - WORKFLOW_OF_USER.UID, - USER.NAME, - groupConcatDistinct(WORKFLOW_OF_PROJECT.PID).as("projects") - ) - .from(WORKFLOW) - .leftJoin(WORKFLOW_USER_ACCESS) - .on(WORKFLOW_USER_ACCESS.WID.eq(WORKFLOW.WID)) - .leftJoin(WORKFLOW_OF_USER) - .on(WORKFLOW_OF_USER.WID.eq(WORKFLOW.WID)) - .leftJoin(USER) - .on(USER.UID.eq(WORKFLOW_OF_USER.UID)) - .leftJoin(WORKFLOW_OF_PROJECT) - .on(WORKFLOW.WID.eq(WORKFLOW_OF_PROJECT.WID)) + val workflowEntries = baseWorkflowSelect() .where(WORKFLOW_USER_ACCESS.UID.eq(user.getUid)) .groupBy(WORKFLOW.WID, WORKFLOW_OF_USER.UID) .fetch() - workflowEntries - .map(workflowRecord => - DashboardWorkflow( - workflowRecord.into(WORKFLOW_OF_USER).getUid.eq(user.getUid), - workflowRecord - .into(WORKFLOW_USER_ACCESS) - .into(classOf[WorkflowUserAccess]) - .getPrivilege - .toString, - workflowRecord.into(USER).getName, - workflowRecord.into(WORKFLOW).into(classOf[Workflow]), - if (workflowRecord.component9() == null) List[UInteger]() - else - workflowRecord.component9().split(',').map(number => UInteger.valueOf(number)).toList, - workflowRecord.into(WORKFLOW_OF_USER).getUid - ) - ) - .asScala - .toList + mapWorkflowEntries(workflowEntries, user.getUid) } /** diff --git a/core/gui/src/app/hub/component/landing-page/landing-page.component.ts b/core/gui/src/app/hub/component/landing-page/landing-page.component.ts index fe663daeb1..014e1af8d2 100644 --- a/core/gui/src/app/hub/component/landing-page/landing-page.component.ts +++ b/core/gui/src/app/hub/component/landing-page/landing-page.component.ts @@ -1,13 +1,12 @@ import { Component, OnInit } from "@angular/core"; -import { Observable } from "rxjs"; +import { firstValueFrom } from "rxjs"; import { HubService } from "../../service/hub.service"; import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; import { Router } from "@angular/router"; -import { DashboardWorkflow } from "../../../dashboard/type/dashboard-workflow.interface"; import { SearchService } from "../../../dashboard/service/user/search.service"; import { DashboardEntry, UserInfo } from "../../../dashboard/type/dashboard-entry"; -import { map, switchMap } from "rxjs/operators"; import { DASHBOARD_HUB_WORKFLOW_RESULT } from "../../../app-routing.constant"; +import { UserService } from "../../../common/service/user/user.service"; @UntilDestroy() @Component({ @@ -16,6 +15,8 @@ import { DASHBOARD_HUB_WORKFLOW_RESULT } from "../../../app-routing.constant"; styleUrls: ["./landing-page.component.scss"], }) export class LandingPageComponent implements OnInit { + public isLogin = this.userService.isLogin(); + public currentUid = this.userService.getCurrentUser()?.uid; public workflowCount: number = 0; public topLovedWorkflows: DashboardEntry[] = []; public topClonedWorkflows: DashboardEntry[] = []; @@ -23,21 +24,30 @@ export class LandingPageComponent implements OnInit { constructor( private hubService: HubService, private router: Router, - private searchService: SearchService - ) {} + private searchService: SearchService, + private userService: UserService + ) { + this.userService + .userChanged() + .pipe(untilDestroyed(this)) + .subscribe(() => { + this.isLogin = this.userService.isLogin(); + this.currentUid = this.userService.getCurrentUser()?.uid; + }); + } ngOnInit(): void { this.getWorkflowCount(); - this.fetchTopWorkflows( - this.hubService.getTopLovedWorkflows(), - workflows => (this.topLovedWorkflows = workflows), - "Top Loved Workflows" - ); - this.fetchTopWorkflows( - this.hubService.getTopClonedWorkflows(), - workflows => (this.topClonedWorkflows = workflows), - "Top Cloned Workflows" - ); + this.loadTops(); + } + + async loadTops() { + try { + this.topLovedWorkflows = await this.getTopLovedEntries("workflow", "like"); + this.topClonedWorkflows = await this.getTopLovedEntries("workflow", "clone"); + } catch (error) { + console.error("Failed to load top loved workflows:", error); + } } getWorkflowCount(): void { @@ -49,48 +59,55 @@ export class LandingPageComponent implements OnInit { }); } - /** - * Helper function to fetch top workflows and associate user info with them. - * @param workflowsObservable Observable that returns workflows (Top Loved or Top Cloned) - * @param updateWorkflowsFn Function to update the component's workflow state - * @param workflowType Label for logging - */ - fetchTopWorkflows( - workflowsObservable: Observable, - updateWorkflowsFn: (entries: DashboardEntry[]) => void, - workflowType: string - ): void { - workflowsObservable - .pipe( - // eslint-disable-next-line rxjs/no-unsafe-takeuntil - untilDestroyed(this), - map((workflows: DashboardWorkflow[]) => { - const userIds = new Set(); - workflows.forEach(workflow => { - userIds.add(workflow.ownerId); - }); - return { workflows, userIds: Array.from(userIds) }; - }), - switchMap(({ workflows, userIds }) => - this.searchService.getUserInfo(userIds).pipe( - map((userIdToInfoMap: { [key: number]: UserInfo }) => { - const dashboardEntries = workflows.map(workflow => { - const userInfo = userIdToInfoMap[workflow.ownerId]; - const entry = new DashboardEntry(workflow); - if (userInfo) { - entry.setOwnerName(userInfo.userName); - entry.setOwnerGoogleAvatar(userInfo.googleAvatar ?? ""); - } - return entry; - }); - return dashboardEntries; - }) - ) - ) - ) - .subscribe((dashboardEntries: DashboardEntry[]) => { - updateWorkflowsFn(dashboardEntries); - }); + // todo: same as the function in search. refactor together + public async getTopLovedEntries(entityType: string, actionType: string): Promise { + const searchResultItems = await firstValueFrom(this.hubService.getTops(entityType, actionType, this.currentUid)); + + const userIds = new Set(); + searchResultItems.forEach(i => { + if (i.workflow) { + userIds.add(i.workflow.ownerId); + } else if (i.project) { + userIds.add(i.project.ownerId); + } else if (i.dataset) { + const ownerUid = i.dataset.dataset?.ownerUid; + if (ownerUid !== undefined) { + userIds.add(ownerUid); + } + } + }); + + let userIdToInfoMap: { [key: number]: UserInfo } = {}; + if (userIds.size > 0) { + userIdToInfoMap = await firstValueFrom(this.searchService.getUserInfo(Array.from(userIds))); + } + + return searchResultItems.map(i => { + let entry: DashboardEntry; + + if (i.workflow) { + entry = new DashboardEntry(i.workflow); + const userInfo = userIdToInfoMap[i.workflow.ownerId]; + if (userInfo) { + entry.setOwnerName(userInfo.userName); + entry.setOwnerGoogleAvatar(userInfo.googleAvatar ?? ""); + } + } else if (i.dataset) { + entry = new DashboardEntry(i.dataset); + const ownerUid = i.dataset.dataset?.ownerUid; + if (ownerUid !== undefined) { + const userInfo = userIdToInfoMap[ownerUid]; + if (userInfo) { + entry.setOwnerName(userInfo.userName); + entry.setOwnerGoogleAvatar(userInfo.googleAvatar ?? ""); + } + } + } else { + throw new Error("Unexpected type in SearchResultItem."); + } + + return entry; + }); } navigateToSearch(): void { diff --git a/core/gui/src/app/hub/service/hub.service.ts b/core/gui/src/app/hub/service/hub.service.ts index 9f8a6fa233..609f2d6bd2 100644 --- a/core/gui/src/app/hub/service/hub.service.ts +++ b/core/gui/src/app/hub/service/hub.service.ts @@ -2,7 +2,7 @@ import { HttpClient, HttpHeaders, HttpParams } from "@angular/common/http"; import { Injectable } from "@angular/core"; import { Observable } from "rxjs"; import { AppSettings } from "../../common/app-setting"; -import { DashboardWorkflow } from "../../dashboard/type/dashboard-workflow.interface"; +import { SearchResultItem } from "../../dashboard/type/search-result"; export const WORKFLOW_BASE_URL = `${AppSettings.getApiEndpoint()}/workflow`; @@ -69,11 +69,14 @@ export class HubService { return this.http.get(`${this.BASE_URL}/viewCount`, { params }); } - public getTopLovedWorkflows(): Observable { - return this.http.get(`${this.BASE_URL}/topLovedWorkflows`); - } + public getTops(entityType: string, actionType: string, currentUid?: number): Observable { + const params: any = { + entityType, + actionType, + }; + + params.uid = currentUid !== undefined ? currentUid : -1; - public getTopClonedWorkflows(): Observable { - return this.http.get(`${this.BASE_URL}/topClonedWorkflows`); + return this.http.get(`${this.BASE_URL}/getTops`, { params }); } } From 4baa80c4ac9c0ea9feb57c1ef4b34d35c67fed89 Mon Sep 17 00:00:00 2001 From: gspikehalo <2318002579@qq.com> Date: Tue, 18 Feb 2025 02:12:49 -0800 Subject: [PATCH 5/8] Add the most liked dataset to the landing page. --- .../resource/dashboard/hub/HubResource.scala | 30 +++++- .../user/dataset/DatasetResource.scala | 83 ++++++++-------- .../browse-section.component.html | 24 ++--- .../browse-section.component.scss | 95 +------------------ .../browse-section.component.ts | 80 +++++++++++++++- .../landing-page/landing-page.component.html | 17 +++- .../landing-page/landing-page.component.ts | 2 + 7 files changed, 172 insertions(+), 159 deletions(-) diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/HubResource.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/HubResource.scala index 2a967bbfde..05d7cc7f3c 100644 --- a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/HubResource.scala +++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/HubResource.scala @@ -3,7 +3,7 @@ package edu.uci.ics.texera.web.resource.dashboard.hub import edu.uci.ics.amber.core.storage.StorageConfig import edu.uci.ics.texera.dao.SqlServer import edu.uci.ics.texera.dao.jooq.generated.Tables._ -import HubResource.{fetchDashboardWorkflowsByWids, getUserLCCount, isLikedHelper, recordLikeActivity, recordUserActivity, userRequest, validateEntityType} +import HubResource.{fetchDashboardDatasetsByDids, fetchDashboardWorkflowsByWids, getUserLCCount, isLikedHelper, recordLikeActivity, recordUserActivity, userRequest, validateEntityType} import edu.uci.ics.texera.web.resource.dashboard.user.workflow.WorkflowResource.{DashboardWorkflow, baseWorkflowSelect, mapWorkflowEntries} import org.jooq.impl.DSL import org.jooq.types.UInteger @@ -16,6 +16,7 @@ import javax.ws.rs.core.{Context, MediaType} import scala.jdk.CollectionConverters._ import EntityTables._ import edu.uci.ics.texera.web.resource.dashboard.DashboardResource.DashboardClickableFileEntry +import edu.uci.ics.texera.web.resource.dashboard.user.dataset.DatasetResource.{DashboardDataset, baseDatasetSelect, mapDashboardDataset} object HubResource { case class userRequest(entityId: UInteger, userId: UInteger, entityType: String) @@ -226,11 +227,25 @@ object HubResource { val records = baseWorkflowSelect() .where(WORKFLOW.WID.in(wids: _*)) - .groupBy(WORKFLOW.WID, WORKFLOW_OF_USER.UID) + .groupBy(WORKFLOW.WID) .fetch() mapWorkflowEntries( records, uid) } + + def fetchDashboardDatasetsByDids(dids: Seq[UInteger], uid: UInteger): List[DashboardDataset] = { + if (dids.isEmpty) { + return List.empty[DashboardDataset] + } + + val records = baseDatasetSelect() + .where(DATASET.DID.in(dids: _*)) + .groupBy(DATASET.DID) + .fetch() + + println(mapDashboardDataset(records, uid)) + mapDashboardDataset(records, uid) + } } @Produces(Array(MediaType.APPLICATION_JSON)) @@ -408,7 +423,16 @@ class HubResource { dataset = None ) } - } else { + } + else if (entityType == "dataset"){ + val datasets = fetchDashboardDatasetsByDids(topEntityIds, currentUid) + datasets.map { d => + DashboardClickableFileEntry( + resourceType = "dataset", workflow = None, project = None, dataset = Some(d) + ) + } + } + else { Seq.empty[DashboardClickableFileEntry] } diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/user/dataset/DatasetResource.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/user/dataset/DatasetResource.scala index 98cb2b3724..77e4d30aed 100644 --- a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/user/dataset/DatasetResource.scala +++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/user/dataset/DatasetResource.scala @@ -1,10 +1,7 @@ package edu.uci.ics.texera.web.resource.dashboard.user.dataset import edu.uci.ics.amber.core.storage.{DocumentFactory, FileResolver, StorageConfig} -import edu.uci.ics.amber.core.storage.util.dataset.{ - GitVersionControlLocalFileStorage, - PhysicalFileNode -} +import edu.uci.ics.amber.core.storage.util.dataset.{GitVersionControlLocalFileStorage, PhysicalFileNode} import edu.uci.ics.amber.engine.common.Utils.withTransaction import edu.uci.ics.amber.util.PathUtils import edu.uci.ics.texera.dao.SqlServer @@ -14,17 +11,8 @@ import edu.uci.ics.texera.dao.jooq.generated.tables.Dataset.DATASET import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetUserAccess.DATASET_USER_ACCESS import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetVersion.DATASET_VERSION import edu.uci.ics.texera.dao.jooq.generated.tables.User.USER -import edu.uci.ics.texera.dao.jooq.generated.tables.daos.{ - DatasetDao, - DatasetUserAccessDao, - DatasetVersionDao -} -import edu.uci.ics.texera.dao.jooq.generated.tables.pojos.{ - Dataset, - DatasetUserAccess, - DatasetVersion, - User -} +import edu.uci.ics.texera.dao.jooq.generated.tables.daos.{DatasetDao, DatasetUserAccessDao, DatasetVersionDao} +import edu.uci.ics.texera.dao.jooq.generated.tables.pojos.{Dataset, DatasetUserAccess, DatasetVersion, User} import edu.uci.ics.texera.web.resource.dashboard.user.dataset.DatasetAccessResource._ import edu.uci.ics.texera.web.resource.dashboard.user.dataset.DatasetResource.{context, _} import edu.uci.ics.texera.web.resource.dashboard.user.dataset.`type`.DatasetFileNode @@ -32,7 +20,7 @@ import io.dropwizard.auth.Auth import org.apache.commons.lang3.StringUtils import org.glassfish.jersey.media.multipart.{FormDataMultiPart, FormDataParam} import org.jooq.types.UInteger -import org.jooq.{DSLContext, EnumType} +import org.jooq.{DSLContext, EnumType, Record, Result, SelectJoinStep} import play.api.libs.json.Json import java.io.{IOException, InputStream, OutputStream} @@ -342,6 +330,34 @@ object DatasetResource { fileNodes: List[DatasetFileNode], size: Long ) + + def baseDatasetSelect(): SelectJoinStep[Record] = { + context + .select() + .from( + DATASET + .leftJoin(DATASET_USER_ACCESS) + .on(DATASET_USER_ACCESS.DID.eq(DATASET.DID)) + .leftJoin(USER) + .on(USER.UID.eq(DATASET.OWNER_UID)) + ) + } + + def mapDashboardDataset(records: Result[Record], uid: UInteger): List[DashboardDataset] = { + records.asScala.map { record => + val dataset = record.into(DATASET).into(classOf[Dataset]) + val datasetAccess = record.into(DATASET_USER_ACCESS).into(classOf[DatasetUserAccess]) + val ownerEmail = record.into(USER).getEmail + DashboardDataset( + isOwner = if (uid == null) false else dataset.getOwnerUid == uid, + dataset = dataset, + accessPrivilege = datasetAccess.getPrivilege, + versions = List(), + ownerEmail = ownerEmail, + size = calculateDatasetVersionSize(dataset.getDid) + ) + }.toList + } } @Produces(Array(MediaType.APPLICATION_JSON, "image/jpeg", "application/pdf")) @@ -626,35 +642,14 @@ class DatasetResource { ): List[DashboardDataset] = { val uid = user.getUid withTransaction(context)(ctx => { - var accessibleDatasets: ListBuffer[DashboardDataset] = ListBuffer() // first fetch all datasets user have explicit access to - accessibleDatasets = ListBuffer.from( - ctx - .select() - .from( - DATASET - .leftJoin(DATASET_USER_ACCESS) - .on(DATASET_USER_ACCESS.DID.eq(DATASET.DID)) - .leftJoin(USER) - .on(USER.UID.eq(DATASET.OWNER_UID)) - ) - .where(DATASET_USER_ACCESS.UID.eq(uid)) - .fetch() - .map(record => { - val dataset = record.into(DATASET).into(classOf[Dataset]) - val datasetAccess = record.into(DATASET_USER_ACCESS).into(classOf[DatasetUserAccess]) - val ownerEmail = record.into(USER).getEmail - DashboardDataset( - isOwner = dataset.getOwnerUid == uid, - dataset = dataset, - accessPrivilege = datasetAccess.getPrivilege, - versions = List(), - ownerEmail = ownerEmail, - size = calculateDatasetVersionSize(dataset.getDid) - ) - }) - .asScala - ) + + val userDatasetRecords = baseDatasetSelect() + .where(DATASET_USER_ACCESS.UID.eq(uid)) + .fetch() + + var accessibleDatasets: ListBuffer[DashboardDataset] = ListBuffer.from(mapDashboardDataset(userDatasetRecords, uid)) + // then we fetch the public datasets and merge it as a part of the result if not exist val publicDatasets = ctx diff --git a/core/gui/src/app/hub/component/browse-section/browse-section.component.html b/core/gui/src/app/hub/component/browse-section/browse-section.component.html index cb1371735a..cf59945834 100644 --- a/core/gui/src/app/hub/component/browse-section/browse-section.component.html +++ b/core/gui/src/app/hub/component/browse-section/browse-section.component.html @@ -1,22 +1,22 @@

{{ sectionTitle }}

-
+
-

{{ workflow.name }}

-

{{ workflow.description || 'No description available' }}

+ class="entity-card" + *ngFor="let entity of entities"> +

{{ entity.name }}

+

{{ entity.description || 'No description available' }}

@@ -27,10 +27,10 @@

{{ workflow.name }}

class="card-cover-image" [src]="defaultBackground" />
diff --git a/core/gui/src/app/hub/component/browse-section/browse-section.component.scss b/core/gui/src/app/hub/component/browse-section/browse-section.component.scss index 1d8fd960ff..8d4cb208a5 100644 --- a/core/gui/src/app/hub/component/browse-section/browse-section.component.scss +++ b/core/gui/src/app/hub/component/browse-section/browse-section.component.scss @@ -1,92 +1,3 @@ -//.results-container { -// display: flex; -// flex-direction: column; -// align-items: flex-start; -// width: 100%; -// padding: 20px; -// -// .results-title { -// font-size: 24px; -// margin-bottom: 20px; -// text-align: left; -// width: 100%; -// padding-left: 10px; -// } -// -// .workflow-cards { -// display: grid; -// grid-template-columns: repeat(4, 1fr); -// grid-gap: 10px; -// width: 100%; -// max-width: 1350px; -// -// .workflow-card { -// margin: 10px; -// box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); -// border-radius: 8px; -// overflow: hidden; -// display: flex; -// flex-direction: column; -// -// .card-title { -// font-size: 18px; -// margin: 10px 0; -// text-align: center; -// white-space: nowrap; -// overflow: hidden; -// text-overflow: ellipsis; -// } -// -// .card-description { -// padding: 0 15px; -// font-size: 14px; -// color: #666; -// display: -webkit-box; -// -webkit-box-orient: vertical; -// -webkit-line-clamp: 2; -// overflow: hidden; -// text-overflow: ellipsis; -// } -// -// .footer { -// margin-top: auto; -// display: flex; -// justify-content: space-between; -// padding: 10px 15px; -// border-top: 1px solid #eee; -// -// .footer-text { -// font-size: 12px; -// color: #999; -// } -// } -// -// .cover-container { -// position: relative; -// width: 100%; -// height: 150px; -// overflow: hidden; -// display: flex; -// justify-content: center; -// align-items: center; -// -// img.card-cover-image { -// width: 100%; -// height: 100%; -// object-fit: cover; -// } -// -// .workflow-avatar { -// position: absolute; -// bottom: 10px; -// left: 10px; -// background-color: grey; -// } -// } -// } -// } -//} - .results-container { display: flex; flex-direction: column; @@ -102,14 +13,14 @@ padding-left: 10px; } - .workflow-cards { + .entity-cards { display: grid; grid-template-columns: repeat(4, 1fr); grid-gap: 10px; width: 100%; max-width: 1350px; - .workflow-card { + .entity-card { margin: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); border-radius: 8px; @@ -173,7 +84,7 @@ object-fit: cover; } - .workflow-avatar { + .entity-avatar { position: absolute; bottom: 10px; left: 10px; diff --git a/core/gui/src/app/hub/component/browse-section/browse-section.component.ts b/core/gui/src/app/hub/component/browse-section/browse-section.component.ts index ff5fcb6750..714e92e7f9 100644 --- a/core/gui/src/app/hub/component/browse-section/browse-section.component.ts +++ b/core/gui/src/app/hub/component/browse-section/browse-section.component.ts @@ -1,15 +1,87 @@ -import { Component, Input } from "@angular/core"; +import { ChangeDetectorRef, Component, Input, OnInit } from "@angular/core"; import { DashboardEntry } from "../../../dashboard/type/dashboard-entry"; -import { DASHBOARD_HUB_WORKFLOW_RESULT_DETAIL } from "../../../app-routing.constant"; +import { WorkflowPersistService } from "../../../common/service/workflow-persist/workflow-persist.service"; +import { DatasetService } from "../../../dashboard/service/user/dataset/dataset.service"; +import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; +import { + DASHBOARD_HUB_WORKFLOW_RESULT_DETAIL, + DASHBOARD_USER_WORKSPACE, + DASHBOARD_USER_DATASET, + DASHBOARD_HUB_DATASET_RESULT_DETAIL, +} from "../../../app-routing.constant"; +@UntilDestroy() @Component({ selector: "texera-browse-section", templateUrl: "./browse-section.component.html", styleUrls: ["./browse-section.component.scss"], }) -export class BrowseSectionComponent { - @Input() workflows: DashboardEntry[] = []; +export class BrowseSectionComponent implements OnInit { + @Input() entities: DashboardEntry[] = []; @Input() sectionTitle: string = ""; + @Input() currentUid: number | undefined; + defaultBackground: string = "../../../../../assets/card_background.jpg"; protected readonly DASHBOARD_HUB_WORKFLOW_RESULT_DETAIL = DASHBOARD_HUB_WORKFLOW_RESULT_DETAIL; + protected readonly DASHBOARD_USER_WORKSPACE = DASHBOARD_USER_WORKSPACE; + protected readonly DASHBOARD_HUB_DATASET_RESULT_DETAIL = DASHBOARD_HUB_DATASET_RESULT_DETAIL; + protected readonly DASHBOARD_USER_DATASET = DASHBOARD_USER_DATASET; + entityRoutes: { [key: number]: string[] } = {}; + + constructor( + private workflowPersistService: WorkflowPersistService, + private datasetService: DatasetService, + private cdr: ChangeDetectorRef + ) {} + + ngOnInit(): void { + this.entities.forEach(entity => { + this.initializeEntry(entity); + }); + } + + ngOnChanges(): void { + this.entities.forEach(entity => { + this.initializeEntry(entity); + }); + } + + private initializeEntry(entity: DashboardEntry): void { + if (typeof entity.id !== "number") { + return; + } + + const entityId = entity.id; + + if (entity.type === "workflow") { + this.workflowPersistService + .getWorkflowOwners(entityId) + .pipe(untilDestroyed(this)) + .subscribe((owners: number[]) => { + if (this.currentUid !== undefined && owners.includes(this.currentUid)) { + this.entityRoutes[entityId] = [this.DASHBOARD_USER_WORKSPACE, String(entityId)]; + } else { + this.entityRoutes[entityId] = [this.DASHBOARD_HUB_WORKFLOW_RESULT_DETAIL, String(entityId)]; + } + this.cdr.detectChanges(); + }); + + } else if (entity.type === "dataset") { + this.datasetService + .getDatasetOwners(entityId) + .pipe(untilDestroyed(this)) + .subscribe((owners: number[]) => { + if (this.currentUid !== undefined && owners.includes(this.currentUid)) { + this.entityRoutes[entityId] = [this.DASHBOARD_USER_DATASET, String(entityId)]; + } else { + this.entityRoutes[entityId] = [this.DASHBOARD_HUB_DATASET_RESULT_DETAIL, String(entityId)]; + } + this.cdr.detectChanges(); + }); + + } else { + throw new Error("Unexpected type in DashboardEntry."); + } + } + } diff --git a/core/gui/src/app/hub/component/landing-page/landing-page.component.html b/core/gui/src/app/hub/component/landing-page/landing-page.component.html index 6d35e8d79a..187569bd96 100644 --- a/core/gui/src/app/hub/component/landing-page/landing-page.component.html +++ b/core/gui/src/app/hub/component/landing-page/landing-page.component.html @@ -20,12 +20,21 @@

Texera Hub

alt="hub icon" />
+
+ [entities]="topLovedWorkflows" + sectionTitle="Top Loved Workflows" + [currentUid]="currentUid"> + [entities]="topClonedWorkflows" + sectionTitle="Top Cloned Workflows" + [currentUid]="currentUid"> + + +
diff --git a/core/gui/src/app/hub/component/landing-page/landing-page.component.ts b/core/gui/src/app/hub/component/landing-page/landing-page.component.ts index 014e1af8d2..afbd98ff79 100644 --- a/core/gui/src/app/hub/component/landing-page/landing-page.component.ts +++ b/core/gui/src/app/hub/component/landing-page/landing-page.component.ts @@ -20,6 +20,7 @@ export class LandingPageComponent implements OnInit { public workflowCount: number = 0; public topLovedWorkflows: DashboardEntry[] = []; public topClonedWorkflows: DashboardEntry[] = []; + public topLovedDatasets: DashboardEntry[] = []; constructor( private hubService: HubService, @@ -45,6 +46,7 @@ export class LandingPageComponent implements OnInit { try { this.topLovedWorkflows = await this.getTopLovedEntries("workflow", "like"); this.topClonedWorkflows = await this.getTopLovedEntries("workflow", "clone"); + this.topLovedDatasets = await this.getTopLovedEntries("dataset", "like"); } catch (error) { console.error("Failed to load top loved workflows:", error); } From 17ae790738027ccaa4fca60531e341e0e11d5bc3 Mon Sep 17 00:00:00 2001 From: gspikehalo <2318002579@qq.com> Date: Wed, 19 Feb 2025 14:05:08 -0800 Subject: [PATCH 6/8] fmt fix --- .../web/resource/dashboard/hub/EntityTables.scala | 14 +++++++------- .../user/list-item/list-item.component.html | 3 +-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/EntityTables.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/EntityTables.scala index 9736294246..bb42647cca 100644 --- a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/EntityTables.scala +++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/EntityTables.scala @@ -122,13 +122,13 @@ object EntityTables { WORKFLOW_VIEW_COUNT.VIEW_COUNT } - case object DatasetViewCountTable extends ViewCountTable { - override type R = DatasetViewCountRecord - override val table: Table[DatasetViewCountRecord] = DATASET_VIEW_COUNT - override val idColumn: TableField[DatasetViewCountRecord, UInteger] = DATASET_VIEW_COUNT.DID - override val viewCountColumn: TableField[DatasetViewCountRecord, UInteger] = - DATASET_VIEW_COUNT.VIEW_COUNT - } + case object DatasetViewCountTable extends ViewCountTable { + override type R = DatasetViewCountRecord + override val table: Table[DatasetViewCountRecord] = DATASET_VIEW_COUNT + override val idColumn: TableField[DatasetViewCountRecord, UInteger] = DATASET_VIEW_COUNT.DID + override val viewCountColumn: TableField[DatasetViewCountRecord, UInteger] = + DATASET_VIEW_COUNT.VIEW_COUNT + } def apply(entityType: String): ViewCountTable = entityType match { diff --git a/core/gui/src/app/dashboard/component/user/list-item/list-item.component.html b/core/gui/src/app/dashboard/component/user/list-item/list-item.component.html index d3c9206e30..0a86c22b30 100644 --- a/core/gui/src/app/dashboard/component/user/list-item/list-item.component.html +++ b/core/gui/src/app/dashboard/component/user/list-item/list-item.component.html @@ -127,8 +127,7 @@ nz-col nzFlex="75px" class="resource-info"> -
+
{{ formatCount(viewCount) }}
views
From 51bb46c1bf8c0179aa3b9f2af490d976bbcde3aa Mon Sep 17 00:00:00 2001 From: gspikehalo <2318002579@qq.com> Date: Wed, 19 Feb 2025 14:15:13 -0800 Subject: [PATCH 7/8] fmt fix --- .../resource/dashboard/hub/HubResource.scala | 50 +++++++++++++------ .../user/dataset/DatasetResource.scala | 22 ++++++-- .../user/workflow/WorkflowResource.scala | 46 ++++++++++++++--- .../browse-section.component.ts | 3 -- .../landing-page/landing-page.component.html | 30 +++++------ 5 files changed, 107 insertions(+), 44 deletions(-) diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/HubResource.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/HubResource.scala index 05d7cc7f3c..d26374fe4e 100644 --- a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/HubResource.scala +++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/hub/HubResource.scala @@ -3,8 +3,21 @@ package edu.uci.ics.texera.web.resource.dashboard.hub import edu.uci.ics.amber.core.storage.StorageConfig import edu.uci.ics.texera.dao.SqlServer import edu.uci.ics.texera.dao.jooq.generated.Tables._ -import HubResource.{fetchDashboardDatasetsByDids, fetchDashboardWorkflowsByWids, getUserLCCount, isLikedHelper, recordLikeActivity, recordUserActivity, userRequest, validateEntityType} -import edu.uci.ics.texera.web.resource.dashboard.user.workflow.WorkflowResource.{DashboardWorkflow, baseWorkflowSelect, mapWorkflowEntries} +import HubResource.{ + fetchDashboardDatasetsByDids, + fetchDashboardWorkflowsByWids, + getUserLCCount, + isLikedHelper, + recordLikeActivity, + recordUserActivity, + userRequest, + validateEntityType +} +import edu.uci.ics.texera.web.resource.dashboard.user.workflow.WorkflowResource.{ + DashboardWorkflow, + baseWorkflowSelect, + mapWorkflowEntries +} import org.jooq.impl.DSL import org.jooq.types.UInteger @@ -16,7 +29,11 @@ import javax.ws.rs.core.{Context, MediaType} import scala.jdk.CollectionConverters._ import EntityTables._ import edu.uci.ics.texera.web.resource.dashboard.DashboardResource.DashboardClickableFileEntry -import edu.uci.ics.texera.web.resource.dashboard.user.dataset.DatasetResource.{DashboardDataset, baseDatasetSelect, mapDashboardDataset} +import edu.uci.ics.texera.web.resource.dashboard.user.dataset.DatasetResource.{ + DashboardDataset, + baseDatasetSelect, + mapDashboardDataset +} object HubResource { case class userRequest(entityId: UInteger, userId: UInteger, entityType: String) @@ -225,12 +242,12 @@ object HubResource { return List.empty[DashboardWorkflow] } - val records = baseWorkflowSelect() - .where(WORKFLOW.WID.in(wids: _*)) - .groupBy(WORKFLOW.WID) - .fetch() + val records = baseWorkflowSelect() + .where(WORKFLOW.WID.in(wids: _*)) + .groupBy(WORKFLOW.WID) + .fetch() - mapWorkflowEntries( records, uid) + mapWorkflowEntries(records, uid) } def fetchDashboardDatasetsByDids(dids: Seq[UInteger], uid: UInteger): List[DashboardDataset] = { @@ -384,7 +401,11 @@ class HubResource { @GET @Path("/getTops") @Produces(Array(MediaType.APPLICATION_JSON)) - def getTops(@QueryParam("entityType") entityType: String, @QueryParam("actionType") actionType: String, @QueryParam("uid") uid: Integer): util.List[DashboardClickableFileEntry] = { + def getTops( + @QueryParam("entityType") entityType: String, + @QueryParam("actionType") actionType: String, + @QueryParam("uid") uid: Integer + ): util.List[DashboardClickableFileEntry] = { validateEntityType(entityType) val baseTable = BaseEntityTable(entityType) @@ -423,16 +444,17 @@ class HubResource { dataset = None ) } - } - else if (entityType == "dataset"){ + } else if (entityType == "dataset") { val datasets = fetchDashboardDatasetsByDids(topEntityIds, currentUid) datasets.map { d => DashboardClickableFileEntry( - resourceType = "dataset", workflow = None, project = None, dataset = Some(d) + resourceType = "dataset", + workflow = None, + project = None, + dataset = Some(d) ) } - } - else { + } else { Seq.empty[DashboardClickableFileEntry] } diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/user/dataset/DatasetResource.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/user/dataset/DatasetResource.scala index 77e4d30aed..ac9165ec54 100644 --- a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/user/dataset/DatasetResource.scala +++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/user/dataset/DatasetResource.scala @@ -1,7 +1,10 @@ package edu.uci.ics.texera.web.resource.dashboard.user.dataset import edu.uci.ics.amber.core.storage.{DocumentFactory, FileResolver, StorageConfig} -import edu.uci.ics.amber.core.storage.util.dataset.{GitVersionControlLocalFileStorage, PhysicalFileNode} +import edu.uci.ics.amber.core.storage.util.dataset.{ + GitVersionControlLocalFileStorage, + PhysicalFileNode +} import edu.uci.ics.amber.engine.common.Utils.withTransaction import edu.uci.ics.amber.util.PathUtils import edu.uci.ics.texera.dao.SqlServer @@ -11,8 +14,17 @@ import edu.uci.ics.texera.dao.jooq.generated.tables.Dataset.DATASET import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetUserAccess.DATASET_USER_ACCESS import edu.uci.ics.texera.dao.jooq.generated.tables.DatasetVersion.DATASET_VERSION import edu.uci.ics.texera.dao.jooq.generated.tables.User.USER -import edu.uci.ics.texera.dao.jooq.generated.tables.daos.{DatasetDao, DatasetUserAccessDao, DatasetVersionDao} -import edu.uci.ics.texera.dao.jooq.generated.tables.pojos.{Dataset, DatasetUserAccess, DatasetVersion, User} +import edu.uci.ics.texera.dao.jooq.generated.tables.daos.{ + DatasetDao, + DatasetUserAccessDao, + DatasetVersionDao +} +import edu.uci.ics.texera.dao.jooq.generated.tables.pojos.{ + Dataset, + DatasetUserAccess, + DatasetVersion, + User +} import edu.uci.ics.texera.web.resource.dashboard.user.dataset.DatasetAccessResource._ import edu.uci.ics.texera.web.resource.dashboard.user.dataset.DatasetResource.{context, _} import edu.uci.ics.texera.web.resource.dashboard.user.dataset.`type`.DatasetFileNode @@ -648,8 +660,8 @@ class DatasetResource { .where(DATASET_USER_ACCESS.UID.eq(uid)) .fetch() - var accessibleDatasets: ListBuffer[DashboardDataset] = ListBuffer.from(mapDashboardDataset(userDatasetRecords, uid)) - + var accessibleDatasets: ListBuffer[DashboardDataset] = + ListBuffer.from(mapDashboardDataset(userDatasetRecords, uid)) // then we fetch the public datasets and merge it as a part of the result if not exist val publicDatasets = ctx diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala index 6e7f417ca8..d5c714ff3a 100644 --- a/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala +++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala @@ -8,7 +8,12 @@ import edu.uci.ics.texera.dao.SqlServer import edu.uci.ics.texera.web.auth.SessionUser import edu.uci.ics.texera.dao.jooq.generated.Tables._ import edu.uci.ics.texera.dao.jooq.generated.enums.WorkflowUserAccessPrivilege -import edu.uci.ics.texera.dao.jooq.generated.tables.daos.{WorkflowDao, WorkflowOfProjectDao, WorkflowOfUserDao, WorkflowUserAccessDao} +import edu.uci.ics.texera.dao.jooq.generated.tables.daos.{ + WorkflowDao, + WorkflowOfProjectDao, + WorkflowOfUserDao, + WorkflowUserAccessDao +} import edu.uci.ics.texera.dao.jooq.generated.tables.pojos._ import edu.uci.ics.texera.web.resource.dashboard.hub.HubResource.recordCloneActivity import edu.uci.ics.texera.web.resource.dashboard.user.workflow.WorkflowAccessResource.hasReadAccess @@ -157,7 +162,17 @@ object WorkflowResource { } } - def baseWorkflowSelect(): SelectOnConditionStep[Record9[UInteger, String, String, Timestamp, Timestamp, WorkflowUserAccessPrivilege, UInteger, String, String]] = { + def baseWorkflowSelect(): SelectOnConditionStep[Record9[ + UInteger, + String, + String, + Timestamp, + Timestamp, + WorkflowUserAccessPrivilege, + UInteger, + String, + String + ]] = { context .select( WORKFLOW.WID, @@ -171,13 +186,30 @@ object WorkflowResource { groupConcatDistinct(WORKFLOW_OF_PROJECT.PID).as("projects") ) .from(WORKFLOW) - .leftJoin(WORKFLOW_USER_ACCESS).on(WORKFLOW_USER_ACCESS.WID.eq(WORKFLOW.WID)) - .leftJoin(WORKFLOW_OF_USER).on(WORKFLOW_OF_USER.WID.eq(WORKFLOW.WID)) - .leftJoin(USER).on(USER.UID.eq(WORKFLOW_OF_USER.UID)) - .leftJoin(WORKFLOW_OF_PROJECT).on(WORKFLOW.WID.eq(WORKFLOW_OF_PROJECT.WID)) + .leftJoin(WORKFLOW_USER_ACCESS) + .on(WORKFLOW_USER_ACCESS.WID.eq(WORKFLOW.WID)) + .leftJoin(WORKFLOW_OF_USER) + .on(WORKFLOW_OF_USER.WID.eq(WORKFLOW.WID)) + .leftJoin(USER) + .on(USER.UID.eq(WORKFLOW_OF_USER.UID)) + .leftJoin(WORKFLOW_OF_PROJECT) + .on(WORKFLOW.WID.eq(WORKFLOW_OF_PROJECT.WID)) } - def mapWorkflowEntries(workflowEntries: Result[Record9[UInteger, String, String, Timestamp, Timestamp, WorkflowUserAccessPrivilege, UInteger, String, String]], uid: UInteger ): List[DashboardWorkflow] = { + def mapWorkflowEntries( + workflowEntries: Result[Record9[ + UInteger, + String, + String, + Timestamp, + Timestamp, + WorkflowUserAccessPrivilege, + UInteger, + String, + String + ]], + uid: UInteger + ): List[DashboardWorkflow] = { workflowEntries .map(workflowRecord => DashboardWorkflow( diff --git a/core/gui/src/app/hub/component/browse-section/browse-section.component.ts b/core/gui/src/app/hub/component/browse-section/browse-section.component.ts index 714e92e7f9..dffedc6c77 100644 --- a/core/gui/src/app/hub/component/browse-section/browse-section.component.ts +++ b/core/gui/src/app/hub/component/browse-section/browse-section.component.ts @@ -65,7 +65,6 @@ export class BrowseSectionComponent implements OnInit { } this.cdr.detectChanges(); }); - } else if (entity.type === "dataset") { this.datasetService .getDatasetOwners(entityId) @@ -78,10 +77,8 @@ export class BrowseSectionComponent implements OnInit { } this.cdr.detectChanges(); }); - } else { throw new Error("Unexpected type in DashboardEntry."); } } - } diff --git a/core/gui/src/app/hub/component/landing-page/landing-page.component.html b/core/gui/src/app/hub/component/landing-page/landing-page.component.html index 187569bd96..2d17015a30 100644 --- a/core/gui/src/app/hub/component/landing-page/landing-page.component.html +++ b/core/gui/src/app/hub/component/landing-page/landing-page.component.html @@ -21,20 +21,20 @@

Texera Hub

- - - - - - + + + + + +
From b73de2c034299b4f359ad3bbed2b0712ae26c57d Mon Sep 17 00:00:00 2001 From: gspikehalo <2318002579@qq.com> Date: Wed, 19 Feb 2025 17:06:01 -0800 Subject: [PATCH 8/8] fix unit test --- .../browse-section/browse-section.component.spec.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/gui/src/app/hub/component/browse-section/browse-section.component.spec.ts b/core/gui/src/app/hub/component/browse-section/browse-section.component.spec.ts index 86c8c9a06c..1eaa5b19f8 100644 --- a/core/gui/src/app/hub/component/browse-section/browse-section.component.spec.ts +++ b/core/gui/src/app/hub/component/browse-section/browse-section.component.spec.ts @@ -1,6 +1,8 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"; - import { BrowseSectionComponent } from "./browse-section.component"; +import { WorkflowPersistService } from "../../../common/service/workflow-persist/workflow-persist.service"; +import { DatasetService } from "../../../dashboard/service/user/dataset/dataset.service"; +import { ChangeDetectorRef } from "@angular/core"; describe("BrowseSectionComponent", () => { let component: BrowseSectionComponent; @@ -9,6 +11,11 @@ describe("BrowseSectionComponent", () => { beforeEach(() => { TestBed.configureTestingModule({ declarations: [BrowseSectionComponent], + providers: [ + { provide: WorkflowPersistService, useValue: {} }, + { provide: DatasetService, useValue: {} }, + { provide: ChangeDetectorRef, useValue: {} }, + ], }); fixture = TestBed.createComponent(BrowseSectionComponent); component = fixture.componentInstance;