Skip to content

Commit

Permalink
Add metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
shiveshnavin committed Sep 10, 2023
1 parent 44a8b84 commit 201ad16
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import io.github.shiveshnavin.firestore.exceptions.FirestoreJDBCException;
import io.github.shiveshnavin.firestore.jdbc.metadata.FirestoreColDefinition;
import io.github.shiveshnavin.firestore.jdbc.metadata.FirestoreColType;
import io.github.shiveshnavin.firestore.jdbc.metadata.FirestoreResultSetMetaData;

import javax.sql.rowset.RowSetMetaDataImpl;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
Expand All @@ -18,24 +20,23 @@ public class FirestoreJDBCResultSet implements ResultSet {
private int index = -1;
private int size = 0;
private List<QuerySnapshotWrapper> queryDocumentSnapshots;
Map<String, FirestoreColDefinition> colDefinitionMap;
private final Map<String, FirestoreColDefinition> colDefinitionMap;

public FirestoreJDBCResultSet(Map<String, FirestoreColDefinition> aliasToColumnMap) {
if (aliasToColumnMap == null)
aliasToColumnMap = new LinkedHashMap<>();
this.colDefinitionMap = aliasToColumnMap;
}

public Map<String, FirestoreColDefinition> getColDefinitionMap(){
if(colDefinitionMap == null){
colDefinitionMap = new HashMap<>();
}

public Map<String, FirestoreColDefinition> getColDefinitionMap() {
return colDefinitionMap;
}

public void setQueryResult(List<QuerySnapshotWrapper> queryResult) {

queryDocumentSnapshots = queryResult;
size = queryDocumentSnapshots.size();
if (size > 0 && getColDefinitionMap().isEmpty()) {
if (size > 0) {

QuerySnapshotWrapper sample = queryDocumentSnapshots.get(0);
Set<String> keys = new HashSet<>();
Expand All @@ -44,11 +45,14 @@ public void setQueryResult(List<QuerySnapshotWrapper> queryResult) {
} else if (sample.getData() != null) {
keys = sample.getData().keySet();
}
if (getColDefinitionMap().isEmpty()) {
int i = 0;
for (String key : keys) {
getColDefinitionMap().put(key, new FirestoreColDefinition(i++, key, FirestoreColType.UNKNOWN));
}
int i = getColDefinitionMap().values()
.stream().mapToInt(FirestoreColDefinition::getIndex)
.max()
.orElse(-1);

for (String key : keys) {
if (!getColDefinitionMap().containsKey(key))
getColDefinitionMap().put(key, new FirestoreColDefinition(++i, key, FirestoreColType.UNKNOWN));
}
}
FJLogger.debug("Retrieved " + size + " rows in result set");
Expand All @@ -60,6 +64,9 @@ public List<QuerySnapshotWrapper> getQueryResult() {
}

private QuerySnapshotWrapper getDocumentPointer() {
if (index < 0 || index >= queryDocumentSnapshots.size()) {
throw new FirestoreJDBCException("Index out of bounds. Must call next() responsibly");
}
return queryDocumentSnapshots.get(index);
}

Expand Down Expand Up @@ -467,32 +474,36 @@ public String getCursorName() throws SQLException {
@Override
public ResultSetMetaData getMetaData() throws SQLException {
printCurrentMethod();

return null;
if (this.getQueryResult() == null || this.getQueryResult().isEmpty()) {
throw new FirestoreJDBCException("Cannot get metadata if the query result is empty.");
}
QuerySnapshotWrapper sample = this.getQueryResult().get(0);
ResultSetMetaData metaData = new FirestoreResultSetMetaData(sample, getColDefinitionMap());
return metaData;
}


@Override
public Object getObject(int i) throws SQLException {
printCurrentMethod();

return null;
return getDocumentPointer().get(getColNameFromIndex(i));
}


@Override
public Object getObject(String s) throws SQLException {
printCurrentMethod();

return null;
return getDocumentPointer().get(s);
}


@Override
public int findColumn(String s) throws SQLException {
printCurrentMethod();

return 0;
return getColDefinitionMap().get(s).getIndex();
}


Expand Down Expand Up @@ -523,8 +534,11 @@ public BigDecimal getBigDecimal(int i) throws SQLException {
@Override
public BigDecimal getBigDecimal(String s) throws SQLException {
printCurrentMethod();
if (getDocumentPointer().getString(s) == null) {
return null;
}
return new BigDecimal(getDocumentPointer().getString(s));

return null;
}


Expand All @@ -548,15 +562,15 @@ public boolean isAfterLast() throws SQLException {
public boolean isFirst() throws SQLException {
printCurrentMethod();

return false;
return index == 0;
}


@Override
public boolean isLast() throws SQLException {
printCurrentMethod();

return false;
return index >= queryDocumentSnapshots.size() - 1;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public class FirestoreJDBCStatement implements java.sql.Statement, PreparedState
private FirestoreJDBCResultSet firestoreJDBCResultSet;
private String originalQuery;
private String query;
private Map<Integer, Integer> paramPositionMap = new HashMap<>();
private Map<Integer, Integer> paramPositionMap = new LinkedHashMap<>();


private Map<String, FirestoreColDefinition> aliasToColumnMap;
Expand Down Expand Up @@ -115,7 +115,7 @@ private String parseQuery() throws FirestoreJDBCException {

private void parseSelect() {
Select stmt = (Select) parsedQuery;
aliasToColumnMap = new HashMap<>();
aliasToColumnMap = new LinkedHashMap<>();
Limit limits = (((PlainSelect) ((Select) parsedQuery).getSelectBody()).getLimit());
if (limits != null) {
if (limits.getRowCount() instanceof LongValue) {
Expand Down Expand Up @@ -262,7 +262,7 @@ private ResultSet performSelectQuery() {
QuerySnapshot querySnapshot = queryFuture.get();
firestoreJDBCResultSet = new FirestoreJDBCResultSet(aliasToColumnMap);
if (isCountQuery) {
HashMap<String, Object> data = new HashMap<>();
HashMap<String, Object> data = new LinkedHashMap<>();
data.put("id", "count");
aliasToColumnMap.keySet().forEach(key -> {
data.put(key, querySnapshot.size());
Expand All @@ -287,7 +287,7 @@ public ResultSet executeQuery(String sql) throws SQLException {
return performSelectQuery();
} else {
int rowCount = executeWOResult(sql);
HashMap<String, Object> data = new HashMap<>();
HashMap<String, Object> data = new LinkedHashMap<>();
data.put("rows", rowCount);
firestoreJDBCResultSet = new FirestoreJDBCResultSet(aliasToColumnMap);
firestoreJDBCResultSet.setQueryResult(List.of(new QuerySnapshotWrapper(null, data)));
Expand Down Expand Up @@ -629,7 +629,7 @@ private int performInsertQuery() throws FirestoreJDBCException {
Insert insert = (Insert) parsedQuery;
List<Column> cols = insert.getColumns();
List<Expression> values = ((ExpressionList) insert.getItemsList()).getExpressions();
Map<String, Object> data = new HashMap<>();
Map<String, Object> data = new LinkedHashMap<>();
for (int i = 0; i < values.size(); i++) {
Expression exp = values.get(i);
Object value = "";
Expand Down Expand Up @@ -666,7 +666,7 @@ private int performInsertQuery() throws FirestoreJDBCException {
private int performUpdateQuery() throws FirestoreJDBCException {
Update update = (Update) parsedQuery;
ArrayList<UpdateSet> updateSets = update.getUpdateSets();
Map<String, Object> data = new HashMap<>();
Map<String, Object> data = new LinkedHashMap<>();
for (int i = 0; i < updateSets.size(); i++) {
UpdateSet updateSet = updateSets.get(i);
Column col = updateSet.getColumns().get(0);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
package io.github.shiveshnavin.firestore.jdbc.metadata;

import com.google.cloud.firestore.QueryDocumentSnapshot;
import io.github.shiveshnavin.firestore.exceptions.FirestoreJDBCException;
import io.github.shiveshnavin.firestore.jdbc.QuerySnapshotWrapper;

import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import static io.github.shiveshnavin.firestore.jdbc.FirestoreJDBCResultSet.printCurrentMethod;

public class FirestoreResultSetMetaData implements ResultSetMetaData {
private final QueryDocumentSnapshot snapshotSample;
private final QuerySnapshotWrapper sample;
private final Map<String, Object> data;
private final Map<String, FirestoreColDefinition> colDefinitionMap;

public FirestoreResultSetMetaData(QuerySnapshotWrapper sample, Map<String, FirestoreColDefinition> colDefinitionMap) {
this.sample = sample;
this.data = sample.getData();
this.colDefinitionMap = colDefinitionMap;
this.snapshotSample = sample.getSnapshot();
}

public Map<String, FirestoreColDefinition> getColDefinitionMap() {
return colDefinitionMap;
}

private String getColNameFromIndex(int idx) {
if (getColDefinitionMap().isEmpty()) {
throw new FirestoreJDBCException("Retrieving columns by index not supported at present.");
}
return getColDefinitionMap().entrySet().stream().
filter(e -> e.getValue().getIndex() == idx).
findAny().get().getValue().getColumnName();
}

@Override
public int getColumnCount() throws SQLException {
printCurrentMethod();
return data.size();
}

@Override
public boolean isAutoIncrement(int column) throws SQLException {
printCurrentMethod();
return false;
}

@Override
public boolean isCaseSensitive(int column) throws SQLException {
printCurrentMethod();
return false;
}

@Override
public boolean isSearchable(int column) throws SQLException {
printCurrentMethod();
return false;
}

@Override
public boolean isCurrency(int column) throws SQLException {
printCurrentMethod();
return false;
}

@Override
public int isNullable(int column) throws SQLException {
printCurrentMethod();
return 0;
}

@Override
public boolean isSigned(int column) throws SQLException {
printCurrentMethod();
return false;
}

@Override
public int getColumnDisplaySize(int column) throws SQLException {
printCurrentMethod();
return 0;
}

@Override
public String getColumnLabel(int column) throws SQLException {
printCurrentMethod();
return getColNameFromIndex(column);
}

@Override
public String getColumnName(int column) throws SQLException {
printCurrentMethod();
return getColNameFromIndex(column);
}

@Override
public String getSchemaName(int column) throws SQLException {
printCurrentMethod();
return getColNameFromIndex(column);
}

@Override
public int getPrecision(int column) throws SQLException {
printCurrentMethod();
return 0;
}

@Override
public int getScale(int column) throws SQLException {
printCurrentMethod();
return 0;
}

@Override
public String getTableName(int column) throws SQLException {
printCurrentMethod();
try {
return this.snapshotSample.getReference().getParent().getId();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

@Override
public String getCatalogName(int column) throws SQLException {
printCurrentMethod();
return null;
}

@Override
public int getColumnType(int column) throws SQLException {
printCurrentMethod();
return 0;
}

@Override
public String getColumnTypeName(int column) throws SQLException {
printCurrentMethod();
Object o = data.get(getColNameFromIndex(column));
if (o == null)
return null;
return o.getClass().getSimpleName();
}

@Override
public boolean isReadOnly(int column) throws SQLException {
printCurrentMethod();
return false;
}

@Override
public boolean isWritable(int column) throws SQLException {
printCurrentMethod();
return false;
}

@Override
public boolean isDefinitelyWritable(int column) throws SQLException {
printCurrentMethod();
return false;
}

@Override
public String getColumnClassName(int column) throws SQLException {
printCurrentMethod();
Object o = data.get(getColumnTypeName(column));
if (o == null)
return null;
return o.getClass().getName();
}

@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
printCurrentMethod();
return null;
}

@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
printCurrentMethod();
return false;
}
}

0 comments on commit 201ad16

Please sign in to comment.