Skip to content

Commit 34ff2ca

Browse files
committed
spring repo version 2
1 parent 5edf695 commit 34ff2ca

File tree

15 files changed

+972
-0
lines changed

15 files changed

+972
-0
lines changed

outstack-spring-repo/pom.xml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>outstack</artifactId>
7+
<groupId>com.cloudimpl.outstack</groupId>
8+
<version>4.0</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>outstack-spring-repo</artifactId>
13+
14+
<properties>
15+
<maven.compiler.source>17</maven.compiler.source>
16+
<maven.compiler.target>17</maven.compiler.target>
17+
</properties>
18+
<dependencies>
19+
<dependency>
20+
<groupId>com.cloudimpl.outstack</groupId>
21+
<artifactId>outstack-spring</artifactId>
22+
<version>${project.version}</version>
23+
</dependency>
24+
</dependencies>
25+
</project>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.cloudimpl.outstack.collection.error;
2+
3+
4+
public enum Collection implements com.cloudimpl.error.core.ErrorCode {
5+
;
6+
private final int errorNo ;
7+
private final String format ;
8+
9+
@Override
10+
public int getErrorNo() {
11+
return this.errorNo ;
12+
}
13+
14+
@Override
15+
public String getFormat() {
16+
return this.format ;
17+
}
18+
19+
Collection(int errorNo, String errorFormat) {
20+
this.errorNo = errorNo;
21+
this.format = errorFormat;
22+
}
23+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.cloudimpl.outstack.repo;
2+
3+
import lombok.Getter;
4+
import lombok.Setter;
5+
import org.springframework.boot.context.properties.ConfigurationProperties;
6+
import org.springframework.context.annotation.Configuration;
7+
8+
@Getter
9+
@Setter
10+
@Configuration
11+
@ConfigurationProperties("postgres.datasource")
12+
public class DatasourceProps {
13+
14+
private String prefix;
15+
16+
private String host;
17+
18+
private String port;
19+
20+
private String database;
21+
22+
private String username;
23+
24+
private String password;
25+
26+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package com.cloudimpl.outstack.repo;
2+
3+
4+
import java.lang.reflect.Field;
5+
import java.util.Objects;
6+
import java.util.Optional;
7+
8+
public abstract class Entity {
9+
private String tid;
10+
private String parentTid;
11+
private transient Field idField;
12+
private Meta meta;
13+
public Entity(){
14+
15+
this.idField = RepoUtil.getIdField(this.getClass());
16+
this.meta = new Meta();
17+
}
18+
19+
public String getTid()
20+
{
21+
if(tid == null)
22+
{
23+
throw new RepoException("tid is null");
24+
}
25+
return tid;
26+
}
27+
28+
public Meta getMeta()
29+
{
30+
if(meta == null)
31+
{
32+
meta = new Meta();
33+
}
34+
return meta;
35+
}
36+
37+
public String id()
38+
{
39+
return RepoUtil.getValue(this,idField);
40+
}
41+
42+
public Optional<String> getParentTid(){
43+
return Optional.ofNullable(parentTid);
44+
}
45+
46+
protected <T extends Entity> T withTid(String tid)
47+
{
48+
this.tid = tid;
49+
return (T)this;
50+
}
51+
52+
protected <T extends Entity> T setParentTid(String tid)
53+
{
54+
this.tid = tid;
55+
return (T)this;
56+
}
57+
58+
@Override
59+
public boolean equals(Object o) {
60+
if (this == o) return true;
61+
if (o == null || getClass() != o.getClass()) return false;
62+
Entity entity = (Entity) o;
63+
return tid.equals(entity.tid);
64+
}
65+
66+
@Override
67+
public int hashCode() {
68+
return Objects.hash(tid);
69+
}
70+
71+
public final class Meta
72+
{
73+
private String tenantId;
74+
private long createdTime;
75+
private long updatedTime;
76+
77+
private Meta()
78+
{
79+
80+
}
81+
82+
protected Meta withTenantId(String tenantId)
83+
{
84+
if(tenantId != null && tenantId.equals("default"))
85+
{
86+
this.tenantId = null;
87+
}else
88+
{
89+
this.tenantId = tenantId;
90+
}
91+
return this;
92+
}
93+
94+
protected Meta withCreatedTime(long createdTime)
95+
{
96+
this.createdTime = createdTime;
97+
return this;
98+
}
99+
100+
protected Meta withUpdatedTime(long updatedTime)
101+
{
102+
this.updatedTime = updatedTime;
103+
return this;
104+
}
105+
106+
public String getTenantId()
107+
{
108+
return tenantId;
109+
}
110+
111+
public long getCreatedTime()
112+
{
113+
return this.createdTime;
114+
}
115+
116+
public long getUpdatedTime()
117+
{
118+
return this.updatedTime;
119+
}
120+
121+
122+
public <T extends Entity> T entity()
123+
{
124+
return (T) Entity.this;
125+
}
126+
127+
}
128+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package com.cloudimpl.outstack.repo;
2+
3+
import com.cloudimpl.rstack.dsl.restql.BinNode;
4+
import com.cloudimpl.rstack.dsl.restql.ConstArrayNode;
5+
import com.cloudimpl.rstack.dsl.restql.ConstBooleanArrayNode;
6+
import com.cloudimpl.rstack.dsl.restql.ConstBooleanNode;
7+
import com.cloudimpl.rstack.dsl.restql.ConstNode;
8+
import com.cloudimpl.rstack.dsl.restql.ConstNumberArrayNode;
9+
import com.cloudimpl.rstack.dsl.restql.ConstNumberNode;
10+
import com.cloudimpl.rstack.dsl.restql.ConstStringArrayNode;
11+
import com.cloudimpl.rstack.dsl.restql.ConstStringNode;
12+
import com.cloudimpl.rstack.dsl.restql.FieldCheckNode;
13+
import com.cloudimpl.rstack.dsl.restql.OrderByExpNode;
14+
import com.cloudimpl.rstack.dsl.restql.OrderByNode;
15+
import com.cloudimpl.rstack.dsl.restql.RelNode;
16+
import com.cloudimpl.rstack.dsl.restql.RestQLNode;
17+
import com.cloudimpl.rstack.dsl.restql.RestQLParser;
18+
import com.google.gson.JsonObject;
19+
20+
import java.util.stream.Collectors;
21+
22+
/**
23+
*
24+
* @author nuwan
25+
*/
26+
public class PostgresSqlNode implements RestQLNode {
27+
28+
@Override
29+
public String eval(RestQLNode node) {
30+
if (node instanceof ConstArrayNode) {
31+
return ConstArrayNode.class.cast(node).getVals().toString();
32+
} else if (node instanceof ConstStringNode) {
33+
return String.valueOf(ConstStringNode.class.cast(node).getVal());
34+
} else if (node instanceof ConstNumberNode) {
35+
return String.valueOf(ConstNumberNode.class.cast(node).getVal());
36+
} else if (node instanceof ConstBooleanNode) {
37+
return String.valueOf(ConstBooleanNode.class.cast(node).getVal());
38+
} else if (node instanceof RelNode) {
39+
RelNode rel = RelNode.class.cast(node);
40+
if (rel.getOp() == RelNode.Op.IN){
41+
return this.inOperator(rel);
42+
} else{
43+
return castToType(convertToJsonField(rel.getFieldName()), rel.getConstNode()) + (rel.getOp() == RelNode.Op.LIKE ? " ILIKE ":(rel.getOp() == RelNode.Op.NOT_LIKE?" NOT ILIKE ":rel.getOp().getOp())) + (String) rel.getConstNode().eval(this);
44+
}
45+
}else if(node instanceof FieldCheckNode) {
46+
FieldCheckNode fieldNode = FieldCheckNode.class.cast(node);
47+
return convertToJsonField(fieldNode.getFieldName()) + (fieldNode.isCheckExist() ? " is not null " : " is null ");
48+
} else if (node instanceof BinNode) {
49+
BinNode binNode = BinNode.class.cast(node);
50+
return "(" + binNode.getLeft().eval(this) + binNode.getOp().getOp() + binNode.getRight().eval(this) + ")";
51+
}else if (node instanceof OrderByNode) {
52+
OrderByNode orderBy = OrderByNode.class.cast(node);
53+
return castToType(convertToJsonField(orderBy.getFieldName()),orderBy.getDataType() )+ " " + orderBy.getOrder();
54+
}else if(node instanceof OrderByExpNode)
55+
{
56+
OrderByExpNode expNode = OrderByExpNode.class.cast(node);
57+
return expNode.getOrderByList().stream().map(i->(String)i.eval(this)).collect(Collectors.joining(","));
58+
}
59+
throw new RuntimeException("unknown node :" + node.getClass().getName());
60+
}
61+
62+
@Override
63+
public JsonObject toJson() {
64+
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
65+
}
66+
67+
private String inOperator(RelNode relNode){
68+
ConstNode constNode = relNode.getConstNode();
69+
if (constNode instanceof ConstStringArrayNode){
70+
return convertToJsonField( relNode.getFieldName() ) + " IN (" + ConstStringArrayNode.class.cast(constNode).getVals().stream().collect(Collectors.joining(",")) + ")";
71+
} else if(constNode instanceof ConstNumberArrayNode){
72+
return convertToJsonField( relNode.getFieldName() ) + " IN (" + ConstNumberArrayNode.class.cast(constNode).getVals().stream().map(v->v.toString()).collect(Collectors.joining(",")) + ")";
73+
} else if(constNode instanceof ConstBooleanArrayNode){
74+
return convertToJsonField( relNode.getFieldName() ) + " IN (" + ConstBooleanArrayNode.class.cast(constNode).getVals().stream().map(v->v.toString()).collect(Collectors.joining(",")) + ")";
75+
} else {
76+
throw new RuntimeException("unknown const array node :" + constNode.getClass().getName());
77+
}
78+
}
79+
80+
public static String convertToJsonField(String field) {
81+
field = field.trim();
82+
if(field.startsWith("_"))
83+
{
84+
return field.substring(1);
85+
}
86+
87+
String[] fields = field.split("\\.");
88+
if (fields.length == 1) {
89+
return "json->>'" + field + "'";
90+
} else if (fields.length == 2) {
91+
return "json->'" + fields[0] + "'->>'" + fields[1] + "'";
92+
} else if (fields.length > 2) {
93+
String param = "json";
94+
for (int i = 0; i < fields.length; i++) {
95+
if (i == fields.length - 1) {
96+
param = param + "->>'" + fields[i] + "'";
97+
} else {
98+
param = param + "->'" + fields[i]+ "'";
99+
}
100+
}
101+
return param;
102+
}
103+
throw new RuntimeException("invalid field format");
104+
}
105+
106+
public static String castToType(String fieldName, ConstNode constNode) {
107+
if (constNode instanceof ConstNumberNode) {
108+
return "(" + fieldName + ")::numeric";
109+
} else if (constNode instanceof ConstBooleanNode) {
110+
return "(" + fieldName + ")::bool";
111+
} else {
112+
return fieldName;
113+
}
114+
}
115+
116+
public static String castToType(String fieldName,OrderByNode.DataType dataType) {
117+
switch(dataType)
118+
{
119+
case BOOL:
120+
{
121+
return "("+fieldName+")::bool";
122+
}
123+
case NUMBER:{
124+
return "("+fieldName+")::numeric";
125+
}
126+
case STRING:
127+
{
128+
return fieldName;
129+
}
130+
default:
131+
{
132+
return fieldName;
133+
}
134+
}
135+
136+
}
137+
138+
public static void main(String[] args) {
139+
RestQLNode node = RestQLParser.parse("_resourceType = 'com.restrata.db.repo.TestEntity'");
140+
PostgresSqlNode sqlNode = new PostgresSqlNode();
141+
System.out.println(sqlNode.eval(node));
142+
}
143+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.cloudimpl.outstack.repo;
2+
3+
import lombok.Builder;
4+
5+
@Builder
6+
7+
public class QueryRequest {
8+
private String query = "";
9+
private String orderBy = "";
10+
private int pageSize = Integer.MAX_VALUE;
11+
private int pageNum = 0;
12+
private boolean mergeNonTenant = false;
13+
14+
public String getQuery()
15+
{
16+
return query == null ? "":query;
17+
}
18+
19+
public String getOrderBy()
20+
{
21+
return orderBy == null ? "":orderBy;
22+
}
23+
24+
public int getPageSize()
25+
{
26+
return pageSize == 0 ? Integer.MAX_VALUE : pageSize;
27+
}
28+
29+
public int getPageNum()
30+
{
31+
return pageNum;
32+
}
33+
34+
public boolean isMergeNonTenant()
35+
{
36+
return this.mergeNonTenant;
37+
}
38+
}

0 commit comments

Comments
 (0)