diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1918528..6c2277b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,15 +2,13 @@ name: Gradle Build on: {push: {tags: null}} jobs: build: - runs-on: self-hosted + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: vaccovecrana/gitflow-oss-java-slim@0.9.9 + - uses: actions/checkout@v4 + - uses: vaccovecrana/gitflow-oss-java-slim@1.0.1 with: - orgConfig: https://vacco-oss.s3.us-east-2.amazonaws.com/vacco-oss.json + orgConfig: http://56db25d3f6c39937b48e-6eaf716421c53330be45fa9d36560381.r85.cf2.rackcdn.com/org-config/vacco.json env: SONATYPE_USER: ${{secrets.SONATYPE_USER}} SONATYPE_PASSWORD: ${{secrets.SONATYPE_PASSWORD}} MAVEN_SIGNING_PRV: ${{secrets.MAVEN_SIGNING_PRV}} - VACCO_CI_USER: ${{secrets.VACCO_CI_USER}} - VACCO_CI_TOKEN: ${{secrets.VACCO_CI_TOKEN}} diff --git a/README.md b/README.md index 5ff4535..3fdaf3c 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,3 @@ This restriction is by design in this framework. # Resources - https://blog.jooq.org/faster-sql-paging-with-jooq-using-the-seek-method - -# Disclaimer - -> This project is not production ready, and still requires security and code correctness audits. You use this -> software at your own risk. Vaccove Crana, LLC., its affiliates and subsidiaries waive any and all liability for any -> damages caused to you by your usage of this software. diff --git a/build.gradle.kts b/build.gradle.kts index 03f25b4..ea1fecc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,10 +1,10 @@ -plugins { id("io.vacco.oss.gitflow") version "0.9.8" apply(false) } +plugins { id("io.vacco.oss.gitflow") version "1.0.1" apply(false) } subprojects { apply(plugin = "io.vacco.oss.gitflow") group = "io.vacco.metolithe" - version = "2.9.6" + version = "2.10.0" configure { addClasspathHell() } configure { resourceExclusions.add("module-info.class") } diff --git a/mt-core/src/main/java/io/vacco/metolithe/core/MtReadDao.java b/mt-core/src/main/java/io/vacco/metolithe/core/MtReadDao.java index ff1dac8..9a02d04 100644 --- a/mt-core/src/main/java/io/vacco/metolithe/core/MtReadDao.java +++ b/mt-core/src/main/java/io/vacco/metolithe/core/MtReadDao.java @@ -74,7 +74,7 @@ private boolean allNonNull(Object[] oa) { return true; } - public List loadPageItems(int pageSize, MtQuery filter, String[] nxf, Object[] nxv) { + public List loadPageItems(int pageSize, boolean reverse, MtQuery filter, String[] nxFld, Object[] nxVal) { try { var qFmt = String.join("\n", "", "select %s from %s where 1=1", // property names, schema name @@ -82,30 +82,38 @@ public List loadPageItems(int pageSize, MtQuery filter, String[] nxf, Object[ "%s", // seek predicate "order by %s limit %s" ); + var nxNn = allNonNull(nxVal); var filterP = filter == null ? "" : format("and (%s)", filter.render()); - var nxNn = allNonNull(nxv); var seekP = ""; - var sk = stream(nxf).map(dsc::getField).toArray(MtFieldDescriptor[]::new); - var skCsv = stream(sk) - .map(MtFieldDescriptor::getFieldName) - .collect(joining(", ")); + var seekFld = stream(nxFld).map(dsc::getField).toArray(MtFieldDescriptor[]::new); if (nxNn) { - var skPar = IntStream.range(0, nxv.length) + var skParam = IntStream.range(0, nxVal.length) .mapToObj(i -> format(":sk%d", i)) .collect(joining(", ")); - seekP = format("and (%s) >= (%s)", skCsv, skPar); + var fldCsv = stream(seekFld) + .map(MtFieldDescriptor::getFieldName) + .collect(joining(", ")); + seekP = format("and (%s) %s (%s)", fldCsv, reverse ? "<=" : ">=", skParam); // and (fld1, fld2, ...) >= (:sk0, :sk1) <- seek keys + } + + var ordFld = new StringBuilder(); + for (int i = 0; i < seekFld.length; i++) { + ordFld.append(format("%s %s", seekFld[i].getFieldName(), reverse ? "desc" : "asc")); + if (i != seekFld.length - 1) { + ordFld.append(", "); + } } var sql = format(qFmt, propNamesCsv(dsc, true), getSchemaName(), - filterP, seekP, skCsv, pageSize + 1 + filterP, seekP, ordFld, pageSize + 1 ); var q = sql().query().select(sql); if (nxNn) { - for (int i = 0; i < nxv.length; i++) { - q = q.namedParam(format("sk%d", i), nxv[i]); + for (int i = 0; i < nxVal.length; i++) { + q = q.namedParam(format("sk%d", i), nxVal[i]); } } if (filter != null) { @@ -116,14 +124,13 @@ public List loadPageItems(int pageSize, MtQuery filter, String[] nxf, Object[ return new ArrayList<>(q.listResult(mapToDefault())); } catch (Exception e) { - throw new MtException.MtPageAccessException(nxf, nxv, dsc, e); + throw new MtException.MtPageAccessException(nxFld, nxVal, dsc, e); } } - public MtPage1 loadPage1(int pageSize, MtQuery filter, - String nx1Fld, K1 nx1) { + public MtPage1 loadPage1(int pageSize, boolean reverse, MtQuery filter, String nx1Fld, K1 nx1) { var page = new MtPage1(); - var items = loadPageItems(pageSize, filter, new String[] {nx1Fld}, new Object[] {nx1}); + var items = loadPageItems(pageSize, reverse, filter, new String[] {nx1Fld}, new Object[] {nx1}); page.items = items; if (items.size() > pageSize) { var next = items.remove(items.size() - 1); @@ -133,11 +140,12 @@ public MtPage1 loadPage1(int pageSize, MtQuery filter, return page; } - public MtPage2 loadPage2(int pageSize, MtQuery filter, + public MtPage2 loadPage2(int pageSize, boolean reverse, + MtQuery filter, String nx1Fld, K1 nx1, String nx2Fld, K2 nx2) { var page = new MtPage2(); - var items = loadPageItems(pageSize, filter, new String[] {nx1Fld, nx2Fld}, new Object[] {nx1, nx2}); + var items = loadPageItems(pageSize, reverse, filter, new String[] {nx1Fld, nx2Fld}, new Object[] {nx1, nx2}); page.items = items; if (items.size() > pageSize) { var next = items.remove(items.size() - 1); diff --git a/mt-test/src/test/java/io/vacco/metolithe/test/MtDaoSpec.java b/mt-test/src/test/java/io/vacco/metolithe/test/MtDaoSpec.java index 826dd16..03d21e7 100644 --- a/mt-test/src/test/java/io/vacco/metolithe/test/MtDaoSpec.java +++ b/mt-test/src/test/java/io/vacco/metolithe/test/MtDaoSpec.java @@ -195,11 +195,11 @@ public class MtDaoSpec extends MtSpec { log.info("======== All phone pages ========"); phones.clear(); - var page0 = pDao.loadPage1(16, null, PhoneDao.fld_number, null); + var page0 = pDao.loadPage1(16, true, null, PhoneDao.fld_number, null); phones.addAll(page0.items); while (page0.nx1 != null) { log.info("{}", kv("page0", page0)); - page0 = pDao.loadPage1(16, null, PhoneDao.fld_number, page0.nx1); + page0 = pDao.loadPage1(16, true, null, PhoneDao.fld_number, page0.nx1); phones.addAll(page0.items); } log.info("{}", kv("page0", page0)); @@ -209,11 +209,11 @@ public class MtDaoSpec extends MtSpec { var fq = MtQuery.of("$0 != :$0") .withSlotValue(PhoneDao.fld_smsVerificationCode) .withParam(PhoneDao.fld_smsVerificationCode, 0); - var page1 = pDao.loadPage1(4, fq, PhoneDao.fld_number, null); + var page1 = pDao.loadPage1(4, false, fq, PhoneDao.fld_number, null); pageSum = pageSum + page1.size; while (page1.nx1 != null) { log.info("{}", kv("page1", page1)); - page1 = pDao.loadPage1(4, fq, PhoneDao.fld_number, page1.nx1); + page1 = pDao.loadPage1(4, false, fq, PhoneDao.fld_number, page1.nx1); pageSum = pageSum + page1.size; } log.info("{}", kv("page1", page1)); @@ -229,14 +229,14 @@ public class MtDaoSpec extends MtSpec { log.info("======== Verified, country code sorted phone pages ========"); var page2 = pDao.loadPage2( - 4, fq, + 4, true, fq, PhoneDao.fld_countryCode, null, PhoneDao.fld_number, null ); while (page2.nx1 != null) { log.info("{}", kv("page2", page2)); page2 = pDao.loadPage2( - 4, fq, + 4, true, fq, PhoneDao.fld_countryCode, page2.nx1, PhoneDao.fld_number, page2.nx2 );