Skip to content

Commit 7afcca4

Browse files
authored
CASL-448 old -> new tests (#402)
* CASL-448 old -> new tests * jira ticket info for property read
1 parent 3ef3807 commit 7afcca4

File tree

11 files changed

+355
-791
lines changed

11 files changed

+355
-791
lines changed

here-naksha-lib-psql/src/commonMain/kotlin/naksha/psql/PgSession.kt

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -310,26 +310,12 @@ open class PgSession(
310310
}
311311
}
312312

313-
private var isTransactionStored = false
314-
private fun saveTransactionIntoDb(create: Boolean = false) {
315-
// FIXME instead of create/update we can use upsert when ready
316-
if (isTransactionStored && create) {
317-
return
318-
} else if (isTransactionStored) {
319-
val updateTxReq = WriteRequest()
320-
val updateTx = Write()
321-
updateTxReq.add(updateTx)
322-
updateTx.updateFeature(null, VIRT_TRANSACTIONS, transaction())
323-
// FIXME uncomment when counts and update ready
324-
// PgWriter(this, updateTxReq).execute()
325-
} else {
326-
val writeTxReq = WriteRequest()
327-
val writeTx = Write()
328-
writeTxReq.add(writeTx)
329-
writeTx.createFeature(null, VIRT_TRANSACTIONS, transaction())
330-
PgWriter(this, writeTxReq, InstantWriteExecutor(this)).execute()
331-
isTransactionStored = true
332-
}
313+
private fun saveTransactionIntoDb() {
314+
val writeTxReq = WriteRequest()
315+
val writeTx = Write()
316+
writeTxReq.add(writeTx)
317+
writeTx.upsertFeature(null, VIRT_TRANSACTIONS, transaction())
318+
PgWriter(this, writeTxReq, InstantWriteExecutor(this)).execute()
333319
}
334320

335321
/**
@@ -363,7 +349,7 @@ open class PgSession(
363349
val tx = transaction
364350
if (tx != null) {
365351
try {
366-
saveTransactionIntoDb(true)
352+
saveTransactionIntoDb()
367353
} catch (e: Throwable) {
368354
throw NakshaException(EXCEPTION, "Failed to save transaction", cause = e)
369355
}

here-naksha-lib-psql/src/commonMain/kotlin/naksha/psql/executors/PgWriter.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ class PgWriter(
278278

279279
// If everything was done perfectly, fine.
280280
val tupleNumberByteArray = TupleNumberByteArray(storage, tupleNumbers.toByteArray())
281+
session.transaction().featuresModified += tupleNumbers.size
281282
return SuccessResponse(
282283
PgResultSet(
283284
storage,
Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
package naksha.psql
2+
3+
import naksha.geo.PointCoord
4+
import naksha.geo.SpGeometry
5+
import naksha.model.Naksha.NakshaCompanion.VIRT_COLLECTIONS
6+
import naksha.model.request.ReadCollections
7+
import naksha.model.request.ReadFeatures
8+
import naksha.model.request.RequestQuery
9+
import naksha.model.request.query.*
10+
import naksha.model.request.query.StringOp.QStringOpCompanion.EQUALS
11+
import naksha.model.request.query.TupleColumn.TupleColumn_C.ID
12+
import naksha.model.request.query.TupleColumn.TupleColumn_C.UID
13+
import naksha.psql.base.PgTestBase
14+
import naksha.psql.executors.query.PgQueryBuilder
15+
import kotlin.test.Test
16+
import kotlin.test.assertEquals
17+
import kotlin.test.assertTrue
18+
19+
@Suppress("UNCHECKED_CAST")
20+
class PgQueryBuilderTest : PgTestBase() {
21+
22+
private val session = storage.newReadSession() as PgSession
23+
24+
@Test
25+
fun testReadNoConditions() {
26+
// given
27+
val req = ReadFeatures().apply { collectionIds += "foo" }
28+
29+
// when
30+
31+
val query = PgQueryBuilder(session, req).build()
32+
33+
// then
34+
assertEquals(0, query.argValues.size)
35+
assertEquals(
36+
"""
37+
SELECT gzip(bytea_agg(tuple_number)) AS rs FROM (SELECT tuple_number FROM (
38+
(SELECT tuple_number, id FROM foo)
39+
) ORDER BY id, tuple_number) LIMIT 1000000;
40+
""".trimIndent(), query.sql.trimIndent()
41+
)
42+
}
43+
44+
@Test
45+
fun testReadMultipleCollections() {
46+
// given
47+
val req = ReadFeatures().apply {
48+
collectionIds += "foo1"
49+
collectionIds += "foo2"
50+
}
51+
52+
// when
53+
val query = PgQueryBuilder(session, req).build()
54+
55+
// then
56+
assertEquals(0, query.argValues.size)
57+
assertEquals(
58+
"""
59+
SELECT gzip(bytea_agg(tuple_number)) AS rs FROM (SELECT tuple_number FROM (
60+
(SELECT tuple_number, id FROM foo1) UNION ALL
61+
(SELECT tuple_number, id FROM foo2)
62+
) ORDER BY id, tuple_number) LIMIT 1000000;
63+
""".trimIndent(), query.sql.trimIndent()
64+
)
65+
}
66+
67+
@Test
68+
fun testReadById() {
69+
// given
70+
val req = ReadFeatures().apply {
71+
collectionIds += "foo"
72+
featureIds += "f1"
73+
}
74+
75+
// when
76+
val query = PgQueryBuilder(session, req).build()
77+
78+
// then
79+
assertEquals(1, query.argValues.size)
80+
assertEquals("f1", (query.argValues[0] as Array<String>)[0])
81+
assertEquals(
82+
"""(SELECT tuple_number, id FROM foo WHERE id = ANY($1))""",
83+
removeLimitWrapper(query.sql)
84+
)
85+
}
86+
87+
@Test
88+
fun testReadWithOr() {
89+
// given
90+
val req = ReadFeatures().apply {
91+
collectionIds += "foo"
92+
featureIds += "f1"
93+
featureIds += "f2"
94+
}
95+
96+
// when
97+
val query = PgQueryBuilder(session, req).build()
98+
99+
// then
100+
assertEquals(1, query.argValues.size)
101+
assertTrue(arrayOf("f1", "f2") contentEquals (query.argValues[0] as Array<String>))
102+
assertEquals(
103+
"""(SELECT tuple_number, id FROM foo WHERE id = ANY($1))""",
104+
removeLimitWrapper(query.sql)
105+
)
106+
}
107+
108+
// TODO FIXME uncomment me once property read is ready (CASL-473).
109+
// @Test
110+
fun testReadWithAnd() {
111+
// given
112+
val req = ReadFeatures().apply {
113+
collectionIds += "foo"
114+
query = RequestQuery().apply {
115+
properties = POr(
116+
PQuery(Property(ID), EQUALS, "f1"),
117+
PAnd(
118+
PQuery(Property(ID), EQUALS, "f2"),
119+
PQuery(Property(UID), DoubleOp.LT, 2.0)
120+
)
121+
)
122+
}
123+
}
124+
125+
// when
126+
val query = PgQueryBuilder(session, req).build()
127+
128+
// then
129+
assertEquals(0, query.argValues.size)
130+
assertEquals(
131+
"""((SELECT tuple_number, id FROM foo WHERE (id=$1 OR (id=$2 AND uid<$3)))""",
132+
removeLimitWrapper(query.sql)
133+
)
134+
}
135+
136+
@Test
137+
fun testReadHistory() {
138+
// given
139+
val req = ReadFeatures().apply {
140+
collectionIds += "foo"
141+
queryHistory = true
142+
}
143+
144+
// when
145+
val query = PgQueryBuilder(session, req).build()
146+
147+
148+
// then
149+
assertEquals(
150+
"""
151+
(SELECT tuple_number, id FROM foo) UNION ALL
152+
(SELECT tuple_number, id FROM "foo${'$'}hst")
153+
""".trimIndent(), removeLimitWrapper(query.sql)
154+
)
155+
}
156+
157+
@Test
158+
fun testReadWithHistoryAndDel() {
159+
// given
160+
val req = ReadFeatures().apply {
161+
collectionIds += "foo"
162+
featureIds += "f1"
163+
queryHistory = true
164+
queryDeleted = true
165+
}
166+
167+
// when
168+
val query = PgQueryBuilder(session, req).build()
169+
170+
171+
// then
172+
assertEquals(
173+
"""
174+
(SELECT tuple_number, id FROM foo WHERE id = ANY(${'$'}1)) UNION ALL
175+
(SELECT tuple_number, id FROM "foo${'$'}del" WHERE id = ANY($1)) UNION ALL
176+
(SELECT tuple_number, id FROM "foo${'$'}hst" WHERE id = ANY($1))
177+
""".trimIndent(), removeLimitWrapper(query.sql)
178+
)
179+
}
180+
181+
182+
@Test
183+
fun testReadBySpatial() {
184+
// given
185+
val req = ReadFeatures().apply {
186+
collectionIds += "foo"
187+
query = RequestQuery().apply {
188+
spatial = SpIntersects(SpGeometry(PointCoord(1.0, 1.0, 1.0)))
189+
}
190+
}
191+
192+
// when
193+
val query = PgQueryBuilder(session, req).build()
194+
195+
// then
196+
assertEquals(
197+
"""(SELECT tuple_number, id FROM foo WHERE (ST_Intersects(naksha_geometry(geo, flags), naksha_geometry($1, 0))))""",
198+
removeLimitWrapper(query.sql)
199+
)
200+
}
201+
202+
@Test
203+
fun testReadBySpatialWithBuffer() {
204+
// given
205+
val geometryTransformation = SpBuffer(22.2, geography = true)
206+
val req = ReadFeatures().apply {
207+
collectionIds += "foo"
208+
query = RequestQuery().apply {
209+
spatial = SpIntersects(SpGeometry(PointCoord(1.0, 1.0, 1.0)), geometryTransformation)
210+
}
211+
}
212+
213+
// when
214+
val query = PgQueryBuilder(session, req).build()
215+
216+
// then
217+
assertEquals(
218+
"""(SELECT tuple_number, id FROM foo WHERE (ST_Intersects(naksha_geometry(geo, flags), ST_Buffer(naksha_geometry($1, 0)::geography, $2))))""",
219+
removeLimitWrapper(query.sql)
220+
)
221+
}
222+
223+
@Test
224+
fun testReadAllCollections() {
225+
// given
226+
val req = ReadCollections()
227+
228+
// when
229+
val query = PgQueryBuilder(session, req).build()
230+
231+
// then
232+
assertEquals(0, query.argValues.size)
233+
assertEquals(
234+
"""(SELECT tuple_number, id FROM "$VIRT_COLLECTIONS")""",
235+
removeLimitWrapper(query.sql)
236+
)
237+
}
238+
239+
@Test
240+
fun testTagsQuery() {
241+
// given
242+
val req = ReadFeatures().apply {
243+
collectionIds += "foo"
244+
query = RequestQuery().apply {
245+
tags = TagExists("stg")
246+
}
247+
}
248+
249+
// when
250+
val query = PgQueryBuilder(session, req).build()
251+
252+
// then
253+
assertEquals(1, query.argValues.size)
254+
assertEquals(
255+
"""(SELECT tuple_number, id FROM foo WHERE (naksha_tags(tags, flags) ?? $1))""",
256+
removeLimitWrapper(query.sql)
257+
)
258+
}
259+
260+
261+
private fun removeLimitWrapper(sql: String) =
262+
sql.replace("SELECT gzip(bytea_agg(tuple_number)) AS rs FROM (SELECT tuple_number FROM (\n", "")
263+
.replace("\n) ORDER BY id, tuple_number) LIMIT 1000000;", "")
264+
.trimIndent()
265+
}

here-naksha-lib-psql/src/commonTest/kotlin/naksha/psql/TransactionsTest.kt

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
package naksha.psql
22

3-
import kotlinx.datetime.Clock.System.now
4-
import kotlinx.datetime.TimeZone.Companion.currentSystemDefault
5-
import kotlinx.datetime.toLocalDateTime
63
import naksha.model.Naksha
74
import naksha.model.NakshaCache
85
import naksha.model.objects.NakshaCollection
96
import naksha.model.objects.NakshaFeature
7+
import naksha.model.objects.Transaction
108
import naksha.model.request.ReadFeatures
119
import naksha.model.request.SuccessResponse
1210
import naksha.model.request.Write
1311
import naksha.model.request.WriteRequest
1412
import naksha.psql.base.PgTestBase
15-
import naksha.psql.util.ProxyFeatureGenerator.generateRandomFeature
16-
import kotlin.test.AfterTest
1713
import kotlin.test.Test
1814
import kotlin.test.assertEquals
15+
import kotlin.test.assertIs
16+
import kotlin.test.assertTrue
1917

2018
class TransactionsTest : PgTestBase(NakshaCollection("transaction_test")) {
2119

@@ -43,4 +41,51 @@ class TransactionsTest : PgTestBase(NakshaCollection("transaction_test")) {
4341
// then
4442
assertEquals(savedFeatureVersion, readResponse.tuples[0]?.tuple?.meta?.version)
4543
}
44+
45+
@Test
46+
fun updateTrasactionInfoOnMultipleWrites() {
47+
// given
48+
val feature1 = NakshaFeature("f2")
49+
val writeRequest1 = WriteRequest().apply { add(Write().createFeature(map = null, collection!!.id, feature1)) }
50+
51+
val feature2 = NakshaFeature("f3")
52+
val writeRequest2 = WriteRequest().apply { add(Write().createFeature(map = null, collection!!.id, feature2)) }
53+
54+
val writeSession = env.storage.newWriteSession(null)
55+
56+
// when
57+
assertIs<SuccessResponse>(writeSession.execute(writeRequest1))
58+
59+
// then
60+
assertEquals(1, writeSession.transaction().featuresModified)
61+
62+
// when
63+
val value = writeSession.execute(writeRequest2)
64+
assertIs<SuccessResponse>(value)
65+
66+
// then
67+
assertEquals(2, writeSession.transaction().featuresModified)
68+
}
69+
70+
@Test
71+
fun shouldBeAbleToTagTransaction() {
72+
// given
73+
val feature = NakshaFeature("f40")
74+
val writeRequest = WriteRequest().apply { add(Write().createFeature(map = null, collection!!.id, feature)) }
75+
76+
val writeSession = env.storage.newWriteSession(null)
77+
78+
// when
79+
writeSession.transaction().properties.xyz.addTag("sth", false)
80+
assertIs<SuccessResponse>(writeSession.execute(writeRequest))
81+
val transactionId = writeSession.transaction().id
82+
writeSession.commit()
83+
84+
// then
85+
val readRequest = ReadFeatures(Naksha.VIRT_TRANSACTIONS).apply {
86+
featureIds += transactionId
87+
}
88+
val readResponse = storage.newReadSession().execute(readRequest) as SuccessResponse
89+
assertTrue(readResponse.features[0]!!.properties.xyz.tags!!.contains("sth"))
90+
}
4691
}

0 commit comments

Comments
 (0)