Query migration to db done - Query persistence in cache is also done

This commit is contained in:
2026-08-01 16:08:52 +05:30
parent 934937feb0
commit 0dae53017d
26 changed files with 608 additions and 1564 deletions

1
.vscode/launch.json vendored
View File

@@ -59,6 +59,7 @@
"REDIS_HOST": "103.125.129.116", "REDIS_HOST": "103.125.129.116",
"REDIS_PORT": "7901", "REDIS_PORT": "7901",
"REDIS_PASSWORD": "M@triXR3d1s@6202", "REDIS_PASSWORD": "M@triXR3d1s@6202",
"REDIS_DATABASE": "1",
"REDIS_SSL": "false", "REDIS_SSL": "false",
"CYGNUS_CLOUD_BASE_URL": "http://localhost:8090", "CYGNUS_CLOUD_BASE_URL": "http://localhost:8090",
"CYGNUS_TOKEN_URL": "http://localhost:8090/oauth2/token", "CYGNUS_TOKEN_URL": "http://localhost:8090/oauth2/token",

View File

@@ -52,10 +52,10 @@ public class CloudIdentityClient {
.timeout(properties.requestTimeout()); .timeout(properties.requestTimeout());
} }
public Mono<CloudQueryResponse> fetchQuery(String queryId) { public Mono<CloudQueryResponse> fetchQuery(int queryId) {
return tokenProvider.accessToken() return tokenProvider.accessToken()
.flatMap(token -> webClient.get() .flatMap(token -> webClient.get()
.uri(properties.baseUri().resolve("/api/v1/queries/").resolve(queryId)) .uri(properties.baseUri().resolve("/api/v1/queries/" + queryId))
.header(HttpHeaders.AUTHORIZATION, "Bearer " + token) .header(HttpHeaders.AUTHORIZATION, "Bearer " + token)
.accept(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)
.retrieve() .retrieve()

View File

@@ -1,5 +1,4 @@
package com.cygnus.client.model; package com.cygnus.client.model;
public record CloudQueryResponse(String queryId, String query) { public record CloudQueryResponse(int queryId, String query) {
} }

View File

@@ -1,5 +1,4 @@
package com.cygnus.cloud.query; package com.cygnus.cloud.query;
public record CloudQuery(String queryId, String query) { public record CloudQuery(int queryId, String query) {
} }

View File

@@ -1,6 +1,6 @@
package com.cygnus.cloud.query; package com.cygnus.cloud.query;
import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Min;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@@ -21,10 +21,8 @@ public class CloudQueryController {
@GetMapping("/{queryId}") @GetMapping("/{queryId}")
public Mono<CloudQuery> query( public Mono<CloudQuery> query(
@PathVariable @PathVariable @Min(1) int queryId) {
@Pattern(regexp = "^[A-Za-z0-9._-]+$") String queryId) {
return repository.findEnabled(queryId) return repository.findEnabled(queryId)
.switchIfEmpty(Mono.error(new QueryNotFoundException(queryId))); .switchIfEmpty(Mono.error(new QueryNotFoundException(queryId)));
} }
} }

View File

@@ -1,57 +0,0 @@
package com.cygnus.cloud.query;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
@Component
public class QueryCatalogInitializer implements ApplicationRunner {
static final String DELIMITER = "!C0L!";
private final QueryCatalogRepository repository;
public QueryCatalogInitializer(QueryCatalogRepository repository) {
this.repository = repository;
}
@Override
public void run(ApplicationArguments arguments) {
List<CloudQuery> queries = readCatalog();
repository.initialize()
.thenMany(Flux.fromIterable(queries)
.concatMap(repository::insertIfAbsent))
.then()
.block(Duration.ofMinutes(2));
}
List<CloudQuery> readCatalog() {
ClassPathResource resource = new ClassPathResource("queries/nimble.qry");
List<CloudQuery> queries = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(
resource.getInputStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
int delimiter = line.indexOf(DELIMITER);
if (delimiter <= 0) {
continue;
}
String queryId = line.substring(0, delimiter).trim();
String query = line.substring(delimiter + DELIMITER.length());
if (queryId.matches("^Query\\d+$") && !query.isBlank()) {
queries.add(new CloudQuery(queryId, query));
}
}
return List.copyOf(queries);
} catch (Exception exception) {
throw new IllegalStateException("Unable to load cloud query catalog", exception);
}
}
}

View File

@@ -11,13 +11,13 @@ public class QueryCatalogRepository {
private static final String INITIALIZE = """ private static final String INITIALIZE = """
CREATE SCHEMA IF NOT EXISTS platform; CREATE SCHEMA IF NOT EXISTS platform;
CREATE TABLE IF NOT EXISTS platform.application_query ( CREATE TABLE IF NOT EXISTS platform.application_query (
query_id varchar(100) PRIMARY KEY, query_id integer PRIMARY KEY,
query_text text NOT NULL, query_text text NOT NULL,
enabled boolean NOT NULL DEFAULT true, enabled boolean NOT NULL DEFAULT true,
created_at timestamptz NOT NULL DEFAULT current_timestamp, created_at timestamptz NOT NULL DEFAULT current_timestamp,
updated_at timestamptz NOT NULL DEFAULT current_timestamp, updated_at timestamptz NOT NULL DEFAULT current_timestamp,
CONSTRAINT ck_platform_application_query_id CONSTRAINT ck_platform_application_query_id
CHECK (query_id ~ '^[A-Za-z0-9._-]+$'), CHECK (query_id > 0),
CONSTRAINT ck_platform_application_query_text CONSTRAINT ck_platform_application_query_text
CHECK (length(btrim(query_text)) > 0) CHECK (length(btrim(query_text)) > 0)
) )
@@ -28,12 +28,6 @@ public class QueryCatalogRepository {
WHERE query_id = $1 WHERE query_id = $1
AND enabled = true AND enabled = true
"""; """;
private static final String INSERT_IF_ABSENT = """
INSERT INTO platform.application_query (query_id, query_text)
VALUES ($1, $2)
ON CONFLICT (query_id) DO NOTHING
""";
private final ReactiveDatabaseClient database; private final ReactiveDatabaseClient database;
public QueryCatalogRepository(ReactiveDatabaseClient database) { public QueryCatalogRepository(ReactiveDatabaseClient database) {
@@ -44,18 +38,11 @@ public class QueryCatalogRepository {
return database.query(INITIALIZE).then(); return database.query(INITIALIZE).then();
} }
public Mono<CloudQuery> findEnabled(String queryId) { public Mono<CloudQuery> findEnabled(int queryId) {
return database.preparedQuery(FIND, Tuple.of(queryId)) return database.preparedQuery(FIND, Tuple.of(queryId))
.flatMapMany(rows -> reactor.core.publisher.Flux.fromIterable(rows)) .flatMapMany(rows -> reactor.core.publisher.Flux.fromIterable(rows))
.next() .next()
.map(row -> new CloudQuery( .map(row -> new CloudQuery(
row.getString("query_id"), row.getString("query_text"))); row.getInteger("query_id"), row.getString("query_text")));
}
public Mono<Void> insertIfAbsent(CloudQuery query) {
return database.preparedUpdate(
INSERT_IF_ABSENT,
Tuple.of(query.queryId(), query.query()))
.then();
} }
} }

View File

@@ -0,0 +1,22 @@
package com.cygnus.cloud.query;
import java.time.Duration;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Component
public class QueryCatalogSchemaInitializer implements ApplicationRunner {
private final QueryCatalogRepository repository;
public QueryCatalogSchemaInitializer(QueryCatalogRepository repository) {
this.repository = repository;
}
@Override
public void run(ApplicationArguments arguments) {
repository.initialize()
.block(Duration.ofMinutes(2));
}
}

View File

@@ -6,8 +6,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND) @ResponseStatus(HttpStatus.NOT_FOUND)
public class QueryNotFoundException extends RuntimeException { public class QueryNotFoundException extends RuntimeException {
public QueryNotFoundException(String queryId) { public QueryNotFoundException(int queryId) {
super("Query was not found: " + queryId); super("Query was not found: " + queryId);
} }
} }

View File

@@ -1,14 +1,13 @@
CREATE SCHEMA IF NOT EXISTS platform; CREATE SCHEMA IF NOT EXISTS platform;
CREATE TABLE IF NOT EXISTS platform.application_query ( CREATE TABLE IF NOT EXISTS platform.application_query (
query_id varchar(100) PRIMARY KEY, query_id integer PRIMARY KEY,
query_text text NOT NULL, query_text text NOT NULL,
enabled boolean NOT NULL DEFAULT true, enabled boolean NOT NULL DEFAULT true,
created_at timestamptz NOT NULL DEFAULT current_timestamp, created_at timestamptz NOT NULL DEFAULT current_timestamp,
updated_at timestamptz NOT NULL DEFAULT current_timestamp, updated_at timestamptz NOT NULL DEFAULT current_timestamp,
CONSTRAINT ck_platform_application_query_id CONSTRAINT ck_platform_application_query_id
CHECK (query_id ~ '^[A-Za-z0-9._-]+$'), CHECK (query_id > 0),
CONSTRAINT ck_platform_application_query_text CONSTRAINT ck_platform_application_query_text
CHECK (length(btrim(query_text)) > 0) CHECK (length(btrim(query_text)) > 0)
); );

View File

@@ -0,0 +1,25 @@
DO $$
DECLARE
current_type text;
BEGIN
SELECT data_type
INTO current_type
FROM information_schema.columns
WHERE table_schema = 'platform'
AND table_name = 'application_query'
AND column_name = 'query_id';
IF current_type IN ('character varying', 'text') THEN
ALTER TABLE platform.application_query
DROP CONSTRAINT IF EXISTS ck_platform_application_query_id;
ALTER TABLE platform.application_query
ALTER COLUMN query_id TYPE integer
USING regexp_replace(query_id, '^Query', '')::integer;
ALTER TABLE platform.application_query
ADD CONSTRAINT ck_platform_application_query_id
CHECK (query_id > 0);
END IF;
END
$$;

File diff suppressed because one or more lines are too long

View File

@@ -1,20 +0,0 @@
package com.cygnus.cloud.query;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
class QueryCatalogInitializerTest {
@Test
void readsUniqueNumericQueryIdsFromCloudCatalog() {
var queries = new QueryCatalogInitializer(null).readCatalog();
assertThat(queries).hasSize(455);
assertThat(queries).extracting(CloudQuery::queryId).doesNotHaveDuplicates();
assertThat(queries).anySatisfy(query -> {
assertThat(query.queryId()).isEqualTo("Query3");
assertThat(query.query()).startsWith("select!C0L!select portfolio_id");
});
}
}

View File

@@ -192,6 +192,7 @@ public class DeploymentWriter {
appendEnvironment(env, "REDIS_HOST", runtime.redisHost()); appendEnvironment(env, "REDIS_HOST", runtime.redisHost());
appendEnvironment(env, "REDIS_PORT", runtime.redisPort()); appendEnvironment(env, "REDIS_PORT", runtime.redisPort());
appendEnvironment(env, "REDIS_PASSWORD", runtime.redisPassword()); appendEnvironment(env, "REDIS_PASSWORD", runtime.redisPassword());
appendEnvironment(env, "REDIS_DATABASE", "1");
appendEnvironment(env, "REDIS_SSL", Boolean.toString(runtime.redisSsl())); appendEnvironment(env, "REDIS_SSL", Boolean.toString(runtime.redisSsl()));
appendEnvironment( appendEnvironment(
env, "CYGNUS_CLOUD_BASE_URL", normalizedCloudServiceUrl(runtime)); env, "CYGNUS_CLOUD_BASE_URL", normalizedCloudServiceUrl(runtime));

View File

@@ -109,6 +109,7 @@ class DeploymentWriterTest {
.contains("MATRIX_IMAGE=\"registry.example.com/matrix:1.0.0\"") .contains("MATRIX_IMAGE=\"registry.example.com/matrix:1.0.0\"")
.contains("MATRIX_DB_URL=\"jdbc:postgresql://db:5432/matrix\"") .contains("MATRIX_DB_URL=\"jdbc:postgresql://db:5432/matrix\"")
.contains("REDIS_HOST=\"redis\"") .contains("REDIS_HOST=\"redis\"")
.contains("REDIS_DATABASE=\"1\"")
.contains("CYGNUS_CLOUD_BASE_URL=\"http://host.docker.internal:8090\"") .contains("CYGNUS_CLOUD_BASE_URL=\"http://host.docker.internal:8090\"")
.contains("CYGNUS_TOKEN_URL=\"http://host.docker.internal:8090/oauth2/token\"") .contains("CYGNUS_TOKEN_URL=\"http://host.docker.internal:8090/oauth2/token\"")
.contains("CYGNUS_CLIENT_ID=\"matrix-client\"") .contains("CYGNUS_CLIENT_ID=\"matrix-client\"")

File diff suppressed because one or more lines are too long

View File

@@ -173,16 +173,6 @@
<build> <build>
<finalName>matrix</finalName> <finalName>matrix</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<!-- Queries are supplied by the cloud query catalog at runtime. -->
<exclude>matrix/nimble/conf/nimble.qry</exclude>
</excludes>
</resource>
</resources>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>

View File

@@ -16,11 +16,16 @@ public class OnPremRedisConfiguration {
@Value("${REDIS_HOST:192.168.0.111}") String host, @Value("${REDIS_HOST:192.168.0.111}") String host,
@Value("${REDIS_PORT:7901}") int port, @Value("${REDIS_PORT:7901}") int port,
@Value("${REDIS_PASSWORD:}") String password, @Value("${REDIS_PASSWORD:}") String password,
@Value("${REDIS_DATABASE:1}") int database,
@Value("${REDIS_SSL:false}") boolean ssl, @Value("${REDIS_SSL:false}") boolean ssl,
@Value("${REDIS_CONNECT_TIMEOUT_SECONDS:3}") long connectTimeoutSeconds) { @Value("${REDIS_CONNECT_TIMEOUT_SECONDS:3}") long connectTimeoutSeconds) {
if (database < 0) {
throw new IllegalArgumentException("REDIS_DATABASE must be zero or greater");
}
RedisURI.Builder uri = RedisURI.builder() RedisURI.Builder uri = RedisURI.builder()
.withHost(host) .withHost(host)
.withPort(port) .withPort(port)
.withDatabase(database)
.withSsl(ssl) .withSsl(ssl)
.withTimeout(Duration.ofSeconds(connectTimeoutSeconds)); .withTimeout(Duration.ofSeconds(connectTimeoutSeconds));
if (password != null && !password.isBlank()) { if (password != null && !password.isBlank()) {

View File

@@ -11,7 +11,7 @@ public final class CloudQuerySource implements QuerySource {
} }
@Override @Override
public String fetch(String queryId) { public String fetch(int queryId) {
return client.fetchQuery(queryId) return client.fetchQuery(queryId)
.map(response -> response.query()) .map(response -> response.query())
.blockOptional() .blockOptional()
@@ -20,4 +20,3 @@ public final class CloudQuerySource implements QuerySource {
"Cloud query was empty: " + queryId)); "Cloud query was empty: " + queryId));
} }
} }

View File

@@ -2,10 +2,5 @@ package matrix.nimble.query;
public interface QueryProvider { public interface QueryProvider {
String getQuery(String queryId); String getQuery(int queryId);
default String getQuery(int queryId) {
return getQuery("Query" + queryId);
}
} }

View File

@@ -3,6 +3,5 @@ package matrix.nimble.query;
@FunctionalInterface @FunctionalInterface
public interface QuerySource { public interface QuerySource {
String fetch(String queryId); String fetch(int queryId);
} }

View File

@@ -30,27 +30,27 @@ public final class RedisCachingQueryProvider implements QueryProvider {
} }
@Override @Override
public String getQuery(String queryId) { public String getQuery(int queryId) {
String normalized = normalize(queryId); String cacheKey = cacheKey(queryId);
Optional<String> cached = cached(normalized); Optional<String> cached = cached(cacheKey);
if (cached.isPresent()) { if (cached.isPresent()) {
return cached.get(); return cached.get();
} }
synchronized (lock(normalized)) { synchronized (lock(cacheKey)) {
cached = cached(normalized); cached = cached(cacheKey);
if (cached.isPresent()) { if (cached.isPresent()) {
return cached.get(); return cached.get();
} }
try { try {
String query = cloudSource.fetch(normalized); String query = cloudSource.fetch(queryId);
cache.put(normalized, cipher.encrypt(normalized, query), QUERY_TTL); cache.put(cacheKey, cipher.encrypt(cacheKey, query), QUERY_TTL);
return query; return query;
} catch (QueryProviderException exception) { } catch (QueryProviderException exception) {
throw exception; throw exception;
} catch (RuntimeException exception) { } catch (RuntimeException exception) {
throw new QueryProviderException( throw new QueryProviderException(
"Unable to retrieve query: " + normalized, exception); "Unable to retrieve query: " + queryId, exception);
} }
} }
} }
@@ -72,10 +72,10 @@ public final class RedisCachingQueryProvider implements QueryProvider {
return locks[(queryId.hashCode() & Integer.MAX_VALUE) % locks.length]; return locks[(queryId.hashCode() & Integer.MAX_VALUE) % locks.length];
} }
private String normalize(String queryId) { private String cacheKey(int queryId) {
if (queryId == null || !queryId.matches("^[A-Za-z0-9._-]+$")) { if (queryId <= 0) {
throw new IllegalArgumentException("Invalid query ID"); throw new IllegalArgumentException("Invalid query ID");
} }
return queryId; return Integer.toString(queryId);
} }
} }

View File

@@ -12,6 +12,6 @@ class FileFunctionsQueryCacheTest {
void delegatesLegacyQueryLookupToQueryProvider() throws Exception { void delegatesLegacyQueryLookupToQueryProvider() throws Exception {
QueryProviders.install(queryId -> "provided:" + queryId); QueryProviders.install(queryId -> "provided:" + queryId);
FileFunctions files = new FileFunctions("TEST"); FileFunctions files = new FileFunctions("TEST");
assertEquals("provided:Query3", files.GetQuery(3)); assertEquals("provided:3", files.GetQuery(3));
} }
} }

View File

@@ -15,13 +15,13 @@ class AesGcmQueryCipherTest {
Arrays.fill(key, (byte) 7); Arrays.fill(key, (byte) 7);
AesGcmQueryCipher cipher = new AesGcmQueryCipher(key); AesGcmQueryCipher cipher = new AesGcmQueryCipher(key);
String encrypted = cipher.encrypt("Query3", "select * from portfolio"); String encrypted = cipher.encrypt("3", "select * from portfolio");
assertNotEquals("select * from portfolio", encrypted); assertNotEquals("select * from portfolio", encrypted);
assertTrue(encrypted.startsWith("v1.")); assertTrue(encrypted.startsWith("v1."));
org.junit.jupiter.api.Assertions.assertEquals( org.junit.jupiter.api.Assertions.assertEquals(
"select * from portfolio", cipher.decrypt("Query3", encrypted)); "select * from portfolio", cipher.decrypt("3", encrypted));
assertThrows(IllegalStateException.class, assertThrows(IllegalStateException.class,
() -> cipher.decrypt("Query4", encrypted)); () -> cipher.decrypt("4", encrypted));
} }
} }

View File

@@ -27,13 +27,13 @@ class RedisCachingQueryProviderTest {
}, },
cipher); cipher);
assertEquals("select!C0L!select 1", provider.getQuery("Query10")); assertEquals("select!C0L!select 1", provider.getQuery(10));
assertEquals("select!C0L!select 1", provider.getQuery("Query10")); assertEquals("select!C0L!select 1", provider.getQuery(10));
assertEquals(1, cloudCalls.get()); assertEquals(1, cloudCalls.get());
assertEquals(Duration.ofHours(3), cache.ttl.get()); assertEquals(Duration.ofHours(3), cache.ttl.get());
org.junit.jupiter.api.Assertions.assertNotEquals( org.junit.jupiter.api.Assertions.assertNotEquals(
"select!C0L!select 1", cache.values.get("Query10")); "select!C0L!select 1", cache.values.get("10"));
} }
@Test @Test
@@ -55,7 +55,7 @@ class RedisCachingQueryProviderTest {
var executor = Executors.newFixedThreadPool(8); var executor = Executors.newFixedThreadPool(8);
try { try {
for (int index = 0; index < 20; index++) { for (int index = 0; index < 20; index++) {
executor.submit(() -> provider.getQuery("Query20")); executor.submit(() -> provider.getQuery(20));
} }
} finally { } finally {
executor.shutdown(); executor.shutdown();

View File

@@ -1,3 +1,5 @@
Query1!C0L!select!C0L!select u.user_id,u.group_id,g.name,b.branch_id,b.branchname,b.branchcode,b.city,c.company_id,c.companyname,c.companycode,u.displayname,u.isactive from app_user u,user_group g,company c,company_branch b where upper(u.loginid)=upper('val0') and u.loginpassword='val1' and u.group_id=g.group_id and u.company_id=c.company_id and u.branch_id=b.branch_id
Query2!C0L!select!C0L!select p.page_id,p.menulabel,p.targeturl,p.parentpage,p.pageorder,up.permission,p.targetwindow,up.requestval,0 as temp from permission up,pages p where up.group_id=val0 and p.isvisible=1 and up.page_id=p.page_id and up.permission <> '000' and up.page_id not in (select page_id from denied_pages where user_id=val1) order by p.parentpage asc,p.pageorder desc
Query3!C0L!select!C0L!select portfolio_id,portname from portfolio where branch_id=val0 and isactive=1 order by portname Query3!C0L!select!C0L!select portfolio_id,portname from portfolio where branch_id=val0 and isactive=1 order by portname
Query4!C0L!select!C0L!select portbranch_id,bkbranchname from portfolio_bank_branch where portfolio_id=val0 and isactive=1 Query4!C0L!select!C0L!select portbranch_id,bkbranchname from portfolio_bank_branch where portfolio_id=val0 and isactive=1
Query5!C0L!select!C0L!select op.opt_value as valfield,op.val_description,op.description from comp_popup_options op where op.branch_id=val0 and val1 order by op.val_description Query5!C0L!select!C0L!select op.opt_value as valfield,op.val_description,op.description from comp_popup_options op where op.branch_id=val0 and val1 order by op.val_description
@@ -9,6 +11,8 @@ Query10!C0L!select!C0L!select control from app_process where page_id=val0 and va
Query11!C0L!select!C0L!select label,control,controlid,valuetypescript,validationscript,style,cssclass,field_id from dynamic_controls where page_id=val0 and portfolio_id=val1 Query11!C0L!select!C0L!select label,control,controlid,valuetypescript,validationscript,style,cssclass,field_id from dynamic_controls where page_id=val0 and portfolio_id=val1
Query12!C0L!select!C0L!select field_id,fieldvalue as valuepart, fieldvalue as textpart from field_value where field_id=val0 order by valorder Query12!C0L!select!C0L!select field_id,fieldvalue as valuepart, fieldvalue as textpart from field_value where field_id=val0 order by valorder
Query13!C0L!select!C0L!select colony_id||'#-#'||pincode||'#-#'||city as id,location as location from colony where upper(location) like 'val0%' val1 order by location Query13!C0L!select!C0L!select colony_id||'#-#'||pincode||'#-#'||city as id,location as location from colony where upper(location) like 'val0%' val1 order by location
Query14!C0L!insert!C0L!insert into user_loginhistory (loginid,logintime) values ('val0','val1')
Query15!C0L!update!C0L!update user_loginhistory set logouttime='val0',ipaddr='val1' where logintime='val2' and upper(loginid)=upper('val3')
Query16!C0L!procedure!C0L!select casepunching ('val0','val1',val2,'val3',val4,val5) Query16!C0L!procedure!C0L!select casepunching ('val0','val1',val2,'val3',val4,val5)
Query17!C0L!update!C0L!update main_operations c set telesheet= COALESCE((select -1 from denied_process d where process_id=9 and d.portfolio_id=(select portfolio_id from main where uuid=c.uuid) and d.isdenied=1),(case when (select rtv+otv from main where uuid=c.uuid) > 0 then 1 else 0 end)), allocation= COALESCE ((select -1 from denied_process d where process_id=7 and d.portfolio_id=(select portfolio_id from main where uuid=c.uuid) and d.isdenied=1),1), sms= COALESCE ((select -1 from denied_process d where process_id=8 and d.portfolio_id=(select portfolio_id from main where uuid=c.uuid) and d.isdenied=1),1), earlier= COALESCE ((select -1 from denied_process d where process_id=11 and d.portfolio_id=(select portfolio_id from main where uuid=c.uuid) and d.isdenied=1),1), negative= COALESCE ((select -1 from denied_process d where process_id=12 and d.portfolio_id=(select portfolio_id from main where uuid=c.uuid) and d.isdenied=1),1), refsheet= COALESCE ((select -1 from denied_process d where process_id=10 and d.portfolio_id=(select portfolio_id from main where uuid=c.uuid) and d.isdenied=1),1), cutoffon='val0',islocked=val3 where (c.cutoffby is null or c.cutoffby=0) and ((select addedby from main m where m.uuid=c.uuid) <> 0) and company_id=val1 and branch_id=val2 and (islocked=0 or islocked='val3') Query17!C0L!update!C0L!update main_operations c set telesheet= COALESCE((select -1 from denied_process d where process_id=9 and d.portfolio_id=(select portfolio_id from main where uuid=c.uuid) and d.isdenied=1),(case when (select rtv+otv from main where uuid=c.uuid) > 0 then 1 else 0 end)), allocation= COALESCE ((select -1 from denied_process d where process_id=7 and d.portfolio_id=(select portfolio_id from main where uuid=c.uuid) and d.isdenied=1),1), sms= COALESCE ((select -1 from denied_process d where process_id=8 and d.portfolio_id=(select portfolio_id from main where uuid=c.uuid) and d.isdenied=1),1), earlier= COALESCE ((select -1 from denied_process d where process_id=11 and d.portfolio_id=(select portfolio_id from main where uuid=c.uuid) and d.isdenied=1),1), negative= COALESCE ((select -1 from denied_process d where process_id=12 and d.portfolio_id=(select portfolio_id from main where uuid=c.uuid) and d.isdenied=1),1), refsheet= COALESCE ((select -1 from denied_process d where process_id=10 and d.portfolio_id=(select portfolio_id from main where uuid=c.uuid) and d.isdenied=1),1), cutoffon='val0',islocked=val3 where (c.cutoffby is null or c.cutoffby=0) and ((select addedby from main m where m.uuid=c.uuid) <> 0) and company_id=val1 and branch_id=val2 and (islocked=0 or islocked='val3')
Query18!C0L!select!C0L!select portfolio_id,(portname||' <b>('||count(*)||')</b>') as portname,(case when sum(allocation)<=0 then -1 else 1 end) as allocation,(case when sum(sms)<=0 then -1 else 1 end) as sms,(case when sum(telesheet)>=1 then 1 else 0 end) as telesheet,(case when sum(earlier)<=0 then -1 else 1 end) as earlier,(case when sum(negative)<=0 then -1 else 1 end) as negative,(case when islocked!=val3 then 1 else 0 end) as islocked,(select (loginid||' ('||displayname||')') from app_user where user_id=islocked) from cutoff_operations c where (cutoffby is null or cutoffby=0) and (select addedby from main m where m.uuid=c.uuid) <> 0 and company_id=val1 and branch_id=val2 group by portfolio_id,portname,islocked Query18!C0L!select!C0L!select portfolio_id,(portname||' <b>('||count(*)||')</b>') as portname,(case when sum(allocation)<=0 then -1 else 1 end) as allocation,(case when sum(sms)<=0 then -1 else 1 end) as sms,(case when sum(telesheet)>=1 then 1 else 0 end) as telesheet,(case when sum(earlier)<=0 then -1 else 1 end) as earlier,(case when sum(negative)<=0 then -1 else 1 end) as negative,(case when islocked!=val3 then 1 else 0 end) as islocked,(select (loginid||' ('||displayname||')') from app_user where user_id=islocked) from cutoff_operations c where (cutoffby is null or cutoffby=0) and (select addedby from main m where m.uuid=c.uuid) <> 0 and company_id=val1 and branch_id=val2 group by portfolio_id,portname,islocked