Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cb 4457 subcollections firestore #2338

Merged
merged 64 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
be16e37
CB-4457. Add api for read subcollections firestore
Jan 26, 2024
66ca0d3
Merge branch 'devel' into CB-4457-subcollections-firestore
devnaumov Jan 26, 2024
dc72807
CB-4457. Move firestore to ee module
Jan 28, 2024
fa0f75c
CB-4457. Move firestore to ee module
Jan 28, 2024
f94eef4
CB-4457. Added annotations for firestore
Jan 29, 2024
171e04f
CB-4457. Added metaData
Jan 29, 2024
a514486
Merge branch 'CB-4457-subcollections-firestore' of https://github.com…
devnaumov Jan 29, 2024
da29798
Merge branch 'devel' into CB-4457-subcollections-firestore
devnaumov Jan 29, 2024
2fcea14
CB-4457. Fixed build
Jan 29, 2024
4c1ceea
Merge branch 'CB-4457-subcollections-firestore' of https://github.com…
devnaumov Jan 29, 2024
52936bb
Merge branch 'devel' into CB-4457-subcollections-firestore
devnaumov Jan 29, 2024
55acd52
CB-4457 add hasChildrenCollection flag
devnaumov Jan 29, 2024
8695dc4
CB-4457. Add new resultsRow
Jan 30, 2024
3282e1e
Merge remote-tracking branch 'origin/CB-4457-subcollections-firestore…
Jan 30, 2024
a034f16
Merge branch 'devel' into CB-4457-subcollections-firestore
DenisSinelnikov Jan 30, 2024
3ec850e
CB-4457. Renamed SQLResultRowMetaData parameters
Jan 30, 2024
b43ac2e
CB-4457 add rows with metadata to schema
devnaumov Jan 30, 2024
c1c3906
CB-4457. Fix gql
Jan 30, 2024
2332f98
CB-4457. Added logic to get Firestore subcollection
Jan 31, 2024
0186f6f
CB-4457. Refactor result, rename gql, added new type to return gql
Jan 31, 2024
a7f5f7f
Merge branch 'devel' into CB-4457-subcollections-firestore
DenisSinelnikov Jan 31, 2024
f69b31b
CB-4457. Revert list to map
Jan 31, 2024
169f4c9
CB-4457. Get Subcollections info
Feb 1, 2024
fcb9e01
CB-4457. Refactor code
Feb 1, 2024
8e0dc4e
Added sceleton for insert subcollection
Feb 2, 2024
7f34943
Merge branch 'devel' into CB-4457-subcollections-firestore
Feb 5, 2024
12d89f8
CB-4457. Added isSupportsDataFilter flag for subcollection
Feb 5, 2024
b590bfc
CB-4457 add locales
devnaumov Feb 5, 2024
0df9749
Merge branch 'devel' into CB-4457-subcollections-firestore
devnaumov Feb 5, 2024
72946a1
Merge remote-tracking branch 'origin/CB-4457-subcollections-firestore…
Feb 5, 2024
3954f87
Merge branch 'devel' into CB-4457-subcollections-firestore
Feb 5, 2024
8b4509d
Merge branch 'subcollections-firestore-insert' into CB-4457-subcollec…
Feb 5, 2024
dda99ed
CB-4457. Added isSupportsDataFilter flag for subcollection
Feb 5, 2024
132fe85
Merge branch 'CB-4457-subcollections-firestore' of https://github.com…
devnaumov Feb 5, 2024
f4f0132
Merge branch 'devel' into CB-4457-subcollections-firestore
devnaumov Feb 5, 2024
2452df1
CB-4457. Added update/insert logic for subcollection
Feb 5, 2024
43d5a7a
Merge branch 'CB-4457-subcollections-firestore' of https://github.com…
devnaumov Feb 5, 2024
77cc3ce
CB-4457 support collection editing
devnaumov Feb 6, 2024
ad3a9b5
Merge branch 'devel' into CB-4457-subcollections-firestore
DenisSinelnikov Feb 6, 2024
2e9dd39
CB-4457. Refactor after review, moved hierarchical model to ee.
Feb 7, 2024
bc72cbd
Merge remote-tracking branch 'origin/CB-4457-subcollections-firestore…
Feb 7, 2024
4a61dff
CB-4457 add SerializableKey
devnaumov Feb 7, 2024
b07fa86
Merge branch 'CB-4457-subcollections-firestore' of https://github.com…
devnaumov Feb 7, 2024
3e0ca83
CB-4457 keep only new rowsWithMetaData api
devnaumov Feb 7, 2024
88c6f85
CB-4457 review fixes
devnaumov Feb 7, 2024
fdb3694
Merge branch 'devel' into CB-4457-subcollections-firestore
devnaumov Feb 7, 2024
c11f17e
Merge remote-tracking branch 'origin/devel' into CB-4457-subcollectio…
Wroud Feb 8, 2024
a1fac7a
CB-4457 review fixes
Wroud Feb 8, 2024
3177f97
CB-4457. Refactor after review. Added logic for delete
Feb 8, 2024
51860c8
Merge branch 'CB-4457-subcollections-firestore' of https://github.com…
devnaumov Feb 8, 2024
38b591e
CB-4457 pass metadata in deleted rows
devnaumov Feb 8, 2024
2e75681
CB-4457 check row for undefined
devnaumov Feb 8, 2024
0adffe5
CB-4457 pass metadata when editing json
devnaumov Feb 8, 2024
c1605b9
CB-4457. Refactor edit, fix icons
Feb 8, 2024
549423d
CB-4457. Refactor makeDocumentInputValue, created new method for locator
Feb 8, 2024
b197aaa
Merge branch 'devel' into CB-4457-subcollections-firestore
dariamarutkina Feb 9, 2024
9af5005
CB-4457 try to get the current metadata for row
devnaumov Feb 12, 2024
44e940d
CB-4457 clear cache on result update
devnaumov Feb 12, 2024
78cbc6d
CB-4457 remove extra check
devnaumov Feb 12, 2024
6b603e7
Merge branch 'devel' into CB-4457-subcollections-firestore
dariamarutkina Feb 12, 2024
9e79b53
CB-4457. Fixed npe
Feb 12, 2024
20e60af
Merge remote-tracking branch 'origin/CB-4457-subcollections-firestore…
Feb 12, 2024
fa19009
Merge branch 'devel' into CB-4457-subcollections-firestore
dariamarutkina Feb 13, 2024
08f0e94
Merge branch 'devel' into CB-4457-subcollections-firestore
dariamarutkina Feb 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion server/bundles/io.cloudbeaver.server/schema/service.sql.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ type SQLResultColumn {
supportedOperations: [DataTypeLogicalOperation!]!
}

type SQLResultRowMetaData {
data: [Object]
metaData: Object
}

type DatabaseDocument {
id: String
contentType: String
Expand All @@ -103,7 +108,8 @@ type DatabaseDocument {
type SQLResultSet {
id: ID!
columns: [ SQLResultColumn ]
rows: [ [ Object ] ]
rows: [ [ Object ] ] @deprecated
rowsWithMetaData: [SQLResultRowMetaData]

# True means that resultset was generated by single entity query
# New rows can be added, old rows can be deleted
Expand All @@ -112,6 +118,8 @@ type SQLResultSet {
hasMoreData: Boolean!
# can't update data or load LOB file if hasRowIdentifier = false
hasRowIdentifier: Boolean!
hasChildrenCollection: Boolean!
isSupportsDataFilter: Boolean!
}

type SQLQueryResults {
Expand Down Expand Up @@ -144,6 +152,12 @@ type SQLExecuteInfo {
input SQLResultRow {
data: [ Object ]!
updateValues: Object
metaData: Object
}

input SQLResultRowMetaDataInput {
data: [Object]
metaData: Object!
}

type DataTypeLogicalOperation {
Expand Down Expand Up @@ -386,4 +400,5 @@ extend type Mutation {
): AsyncTaskInfo!

asyncSqlRowDataCountResult(taskId: ID!): Int!

}
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@
{
// we don't need to add same row several times
// (it can be when we update the row from RS with several tables)
Set<Object[]> newResultSetRows = new LinkedHashSet<>();
Set<WebSQLQueryResultSetRow> newResultSetRows = new LinkedHashSet<>();
KeyDataReceiver keyReceiver = new KeyDataReceiver(contextInfo.getResults(resultsId));
WebSQLResultsInfo resultsInfo = contextInfo.getResults(resultsId);

Expand Down Expand Up @@ -372,7 +372,7 @@

totalUpdateCount += statistics.getRowsUpdated();
result.setDuration(result.getDuration() + statistics.getExecuteTime());
newResultSetRows.add(rowValues);
newResultSetRows.add(new WebSQLQueryResultSetRow(rowValues, null));
}

if (txnManager != null && txnManager.isSupportsTransactions()) {
Expand All @@ -399,7 +399,7 @@
WebSQLQueryResults updateResults = new WebSQLQueryResults(webSession, dataFormat);
updateResults.setUpdateRowCount(totalUpdateCount);
updateResults.setResultSet(updatedResultSet);
updatedResultSet.setRows(newResultSetRows.toArray(new Object[0][]));
updatedResultSet.setRows(List.of(newResultSetRows.toArray(new WebSQLQueryResultSetRow[0])));

queryResults.add(updateResults);

Expand All @@ -410,7 +410,7 @@

private void getUpdatedRowsInfo(
@NotNull WebSQLResultsInfo resultsInfo,
@NotNull Set<Object[]> newResultSetRows,
@NotNull Set<WebSQLQueryResultSetRow> newResultSetRows,
@Nullable WebDataFormat dataFormat,
@NotNull DBRProgressMonitor monitor)
throws DBCException {
Expand All @@ -420,8 +420,8 @@
"Refresh row(s) after insert/update")
) {
boolean canRefreshResults = resultsInfo.canRefreshResults();
for (Object[] row : newResultSetRows) {
if (row.length == 0) {
for (WebSQLQueryResultSetRow row : newResultSetRows) {
if (row.getData().length == 0) {
continue;
}
if (!canRefreshResults) {
Expand All @@ -438,7 +438,7 @@
if (attr.getRowIdentifier() == null) {
continue;
}
final Object keyValue = row[attr.getOrdinalPosition()];
final Object keyValue = row.getData()[attr.getOrdinalPosition()];
if (DBUtils.isNullValue(keyValue)) {
hasKey = false;
break;
Expand All @@ -455,7 +455,7 @@
}
DBDDataFilter filter = new DBDDataFilter(constraints);
DBSDataContainer dataContainer = resultsInfo.getDataContainer();
WebRowDataReceiver dataReceiver = new WebRowDataReceiver(resultsInfo.getAttributes(), row, dataFormat);
WebRowDataReceiver dataReceiver = new WebRowDataReceiver(resultsInfo.getAttributes(), row.getData(), dataFormat);
dataContainer.readData(
new AbstractExecutionSource(dataContainer, getExecutionContext(dataContainer), this),
session,
Expand All @@ -471,14 +471,14 @@

private void makeWebCellRow(
@NotNull WebSQLResultsInfo resultsInfo,
@NotNull Object[] row,
@NotNull WebSQLQueryResultSetRow row,
@Nullable WebDataFormat dataFormat
) throws DBCException {
for (int i = 0; i < row.length; i++) {
row[i] = WebSQLUtils.makeWebCellValue(
for (int i = 0; i < row.getData().length; i++) {
row.getData()[i] = WebSQLUtils.makeWebCellValue(
webSession,
resultsInfo.getAttributeByPosition(i),
row[i],
row.getData()[i],
dataFormat);
}
}
Expand Down Expand Up @@ -563,6 +563,11 @@
Map<String, Object> updateValues = row.getUpdateValues().entrySet().stream()
.filter(x -> CommonUtils.equalObjects(allAttributes[CommonUtils.toInt(x.getKey())].getRowIdentifier(), rowIdentifier))
.collect(HashMap::new, (m,v) -> m.put(v.getKey(), v.getValue()), HashMap::putAll);

Map<String, Object> metaData = row.getMetaData().entrySet().stream()
.filter(x -> CommonUtils.equalObjects(allAttributes[CommonUtils.toInt(x.getKey())].getRowIdentifier(), rowIdentifier))

Check warning on line 568 in server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java

View check run for this annotation

Jenkins-CI-integration / CheckStyle Java Report

server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java#L568

Line is longer than 140 characters (found 146).
.collect(HashMap::new, (m,v) -> m.put(v.getKey(), v.getValue()), HashMap::putAll);

Check warning on line 569 in server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java

View check run for this annotation

Jenkins-CI-integration / CheckStyle Java Report

server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java#L569

, is not followed by whitespace.

if (finalRow.length == 0 || CommonUtils.isEmpty(updateValues)) {
continue;
}
Expand All @@ -582,7 +587,7 @@
boolean isDocumentValue = keyAttributes.length == 1 && keyAttribute.getDataKind() == DBPDataKind.DOCUMENT && dataContainer instanceof DBSDocumentLocator;
if (isDocumentValue) {
rowValues[updateAttributes.length + i] =
makeDocumentInputValue(session, (DBSDocumentLocator) dataContainer, resultsInfo, row);
makeDocumentInputValue(session, (DBSDocumentLocator) dataContainer, resultsInfo, row, metaData);
} else {
rowValues[updateAttributes.length + i] = keyAttribute.getValueHandler().getValueFromObject(
session,
Expand Down Expand Up @@ -693,7 +698,8 @@
DBCSession session,
DBSDocumentLocator dataContainer,
WebSQLResultsInfo resultsInfo,
WebSQLResultsRow row) throws DBException
WebSQLResultsRow row,
Map<String, Object> metaData) throws DBException
{
// Document reference
DBDDocument document = null;
Expand All @@ -711,7 +717,7 @@
keyMap.put(attr.getName(), plainValue);
}
if (document == null) {
document = dataContainer.findDocument(session.getProgressMonitor(), keyMap);
document = dataContainer.findDocument(session, keyMap, metaData);
if (document == null) {
throw new DBCException("Error finding document by key " + keyMap);
}
Expand Down Expand Up @@ -826,7 +832,7 @@
boolean isDocumentValue = keyAttributes.length == 1 && keyAttribute.getDataKind() == DBPDataKind.DOCUMENT && dataContainer instanceof DBSDocumentLocator;
if (isDocumentValue) {
rowValues[i] =
makeDocumentInputValue(session, (DBSDocumentLocator) dataContainer, resultsInfo, row);
makeDocumentInputValue(session, (DBSDocumentLocator) dataContainer, resultsInfo, row, null);
} else {
Object inputCellValue = row.getData()[keyAttribute.getOrdinalPosition()];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@
import org.jkiss.dbeaver.model.data.*;
import org.jkiss.dbeaver.model.exec.*;
import org.jkiss.dbeaver.model.impl.data.DBDValueError;
import org.jkiss.dbeaver.model.meta.MetaData;
import org.jkiss.dbeaver.model.sql.DBQuotaException;
import org.jkiss.dbeaver.model.struct.DBSDataContainer;
import org.jkiss.dbeaver.model.struct.DBSEntity;
import org.jkiss.utils.CommonUtils;

import java.util.ArrayList;
import java.util.List;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

class WebSQLQueryDataReceiver implements DBDDataReceiver {
private static final Log log = Log.getLog(WebSQLQueryDataReceiver.class);
Expand All @@ -42,7 +44,7 @@
private final WebSQLQueryResultSet webResultSet = new WebSQLQueryResultSet();

private DBDAttributeBinding[] bindings;
private List<Object[]> rows = new ArrayList<>();
private List<WebSQLQueryResultSetRow> rows = new ArrayList<>();
private final Number rowLimit;

WebSQLQueryDataReceiver(WebSQLContextInfo contextInfo, DBSDataContainer dataContainer, WebDataFormat dataFormat) {
Expand Down Expand Up @@ -70,6 +72,7 @@
@Override
public void fetchRow(DBCSession session, DBCResultSet resultSet) throws DBCException {

Map<String, Object> metaDataMap = null;
Object[] row = new Object[bindings.length];

for (int i = 0; i < bindings.length; i++) {
Expand All @@ -81,12 +84,23 @@
binding.getMetaAttribute(),
i);
row[i] = cellValue;
Method[] methods = Objects.requireNonNull(cellValue).getClass().getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(MetaData.class)){

Check warning on line 89 in server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLQueryDataReceiver.java

View check run for this annotation

Jenkins-CI-integration / CheckStyle Java Report

server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLQueryDataReceiver.java#L89

WhitespaceAround: [ is not preceded with whitespace.
if (metaDataMap == null) {
metaDataMap = new HashMap<>();
}
Object value = method.invoke(cellValue);
metaDataMap.put(method.getAnnotation(MetaData.class).name(), value);
}
}

} catch (Throwable e) {
row[i] = new DBDValueError(e);
}
}

rows.add(row);
rows.add(new WebSQLQueryResultSetRow(row, metaDataMap));

if (rowLimit != null && rows.size() > rowLimit.longValue()) {
throw new DBQuotaException(
Expand All @@ -101,7 +115,7 @@
DBSEntity entity = dataContainer instanceof DBSEntity ? (DBSEntity) dataContainer : null;

try {
DBExecUtils.bindAttributes(session, entity, resultSet, bindings, rows);
DBExecUtils.bindAttributes(session, entity, resultSet, bindings, rows.stream().map(WebSQLQueryResultSetRow::getData).collect(Collectors.toList()));

Check warning on line 118 in server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLQueryDataReceiver.java

View check run for this annotation

Jenkins-CI-integration / CheckStyle Java Report

server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLQueryDataReceiver.java#L118

Line is longer than 140 characters (found 159).
} catch (DBException e) {
log.error("Error binding attributes", e);
}
Expand All @@ -122,15 +136,17 @@
}

// Convert row values
for (Object[] row : rows) {
for (WebSQLQueryResultSetRow row : rows) {
for (int i = 0; i < bindings.length; i++) {
DBDAttributeBinding binding = bindings[i];
row[i] = WebSQLUtils.makeWebCellValue(webSession, binding, row[i], dataFormat);
row.getData()[i] = WebSQLUtils.makeWebCellValue(webSession, binding, row.getData()[i], dataFormat);
}
}

webResultSet.setColumns(bindings);
webResultSet.setRows(rows.toArray(new Object[0][]));
webResultSet.setRows(List.of(rows.toArray(new WebSQLQueryResultSetRow[0])));
webResultSet.setHasChildrenCollection(resultSet instanceof DBDSubCollectionResultSet);
webResultSet.setSupportsDataFilter(dataContainer.isFeatureSupported(DBSDataContainer.FEATURE_DATA_FILTER));

WebSQLResultsInfo resultsInfo = contextInfo.saveResult(dataContainer, bindings);
webResultSet.setResultsInfo(resultsInfo);
Expand All @@ -157,14 +173,14 @@
// Convert original rows into new rows with leaf attributes
// Extract values for leaf attributes from original row
DBDAttributeBinding[] leafAttributes = leafBindings.toArray(new DBDAttributeBinding[0]);
List<Object[]> newRows = new ArrayList<>();
for (Object[] row : rows) {
List<WebSQLQueryResultSetRow> newRows = new ArrayList<>();
for (WebSQLQueryResultSetRow row : rows) {
Object[] newRow = new Object[leafBindings.size()];
for (int i = 0; i < leafBindings.size(); i++) {
DBDAttributeBinding leafAttr = leafBindings.get(i);
try {
//Object topValue = row[leafAttr.getTopParent().getOrdinalPosition()];
Object cellValue = DBUtils.getAttributeValue(leafAttr, leafAttributes, row);
Object cellValue = DBUtils.getAttributeValue(leafAttr, leafAttributes, row.getData());
/*
Object cellValue = leafAttr.getValueHandler().getValueFromObject(
session,
Expand All @@ -178,7 +194,7 @@
newRow[i] = new DBDValueError(e);
}
}
newRows.add(newRow);
newRows.add(new WebSQLQueryResultSetRow(newRow, row.getMetaData()));
}
this.bindings = leafAttributes;
this.rows = newRows;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
import org.jkiss.dbeaver.model.meta.Property;
import org.jkiss.utils.Pair;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
* Web SQL query resultset.
Expand All @@ -28,12 +33,15 @@ public class WebSQLQueryResultSet {
private static final Log log = Log.getLog(WebSQLQueryResultSet.class);

private WebSQLQueryResultColumn[] columns;
private Object[][] rows;
private List<WebSQLQueryResultSetRow> rows;
private boolean hasMoreData;
private WebSQLResultsInfo resultsInfo;
private boolean singleEntity = true;
private boolean hasRowIdentifier;

private boolean hasChildrenCollection;
private boolean isSupportsDataFilter;

public WebSQLQueryResultSet() {
}

Expand All @@ -60,11 +68,17 @@ public void setColumns(DBDAttributeBinding[] bindings) {
}

@Property
@Deprecated
public Object[][] getRows() {
return rows.stream().map(WebSQLQueryResultSetRow::getData).toArray(x -> new Object[x][1]);
}

@Property
public List<WebSQLQueryResultSetRow> getRowsWithMetaData() {
return rows;
}

public void setRows(Object[][] rows) {
public void setRows(List<WebSQLQueryResultSetRow> rows) {
this.rows = rows;
}

Expand Down Expand Up @@ -102,4 +116,22 @@ public boolean isHasRowIdentifier() {
public void setHasRowIdentifier(boolean hasRowIdentifier) {
this.hasRowIdentifier = hasRowIdentifier;
}

@Property
public boolean isHasChildrenCollection() {
return hasChildrenCollection;
}

public void setHasChildrenCollection(boolean hasSuCollection) {
this.hasChildrenCollection = hasSuCollection;
}

@Property
public boolean isSupportsDataFilter() {
return isSupportsDataFilter;
}

public void setSupportsDataFilter(boolean supportsDataFilter) {
isSupportsDataFilter = supportsDataFilter;
}
}
Loading
Loading