zondag 29 december 2024

PostgreSQL: Making a stored procedure for retrieving groups

After this, ofcourse you want to do something like:

select * from allgroups(1000);

Then you need a function that returns a resultset in PostgreSQL:

CREATE OR REPLACE FUNCTION public.allgroups(p_id int8)

RETURNS table (res_group_id int8)

LANGUAGE plpgsql

AS $function$

begin


return query

with recursive groups AS (

select

g.id as group_id,

gm.member_group_id as member_group_id

from "group" g

left outer join group_member gm on gm.group_id = g.id and gm.member_group_id is not null -- welke groepen zijn members van de huidige groep?

where g.id = p_id

--

union

--

select

g.id as group_id,

gm.member_group_id as member_group_id

from "group" g

left outer join group_member gm on gm.group_id = g.id and gm.member_group_id is not null -- welke groepen zijn members van de huidige groep?

inner join groups rg on rg.member_group_id = g.id -- we doen de query vanuit de member_group_id van het resultaat van de recursie

)

select distinct(group_id) from groups;


end;

$function$

;

 And a count function:

CREATE OR REPLACE FUNCTION public.allgroupscount(p_id int8)

RETURNS int8

LANGUAGE plpgsql

AS $function$

begin

return (select count(*) from public.allgroups(p_id));

end;

$function$

;


PostgreSQL: recursive query

Suppose you have the following sql tables:
Table "group"
id: int8
name: varchar

Table "group_member"
id: int8
group_id: int8
member_user_id: int8
member_group_id: int8


The column member_group_id is filled when you have a group
that is part of the group identified with group_id.

Suppose you want to determine all groups that are part of a 
specific group. You need a recursive query for that:

-- Met deze query willen we alle groepen bepalen die in onze
-- groep zitten.
-- Als een groep lid is van onze groep, dan zijn dat ook 
-- users die we moeten ophalen.
-- we moeten dus de huidige groep en de groepen die lid 
-- zijn van onze groep bepalen. En dat recursief.
with recursive groups AS (
  select
    g.id as group_id,
    gm.member_group_id as member_group_id
  from "group" g
  -- welke groepen zijn members van de huidige groep?
  left outer join group_member gm on gm.group_id = g.id and gm.member_group_id is not null
  where g.id = specific_group_id
  --  
  union
  --
  select
    g.id as group_id,
    gm.member_group_id as member_group_id
  from "group" g
  -- welke groepen zijn members van de huidige groep?
  left outer join group_member gm on gm.group_id = g.id and gm.member_group_id is not null
  -- we doen de query vanuit de member_group_id van het resultaat van de recursie
  inner join groups rg on rg.member_group_id = g.id
)
select distinct(group_id) from groups;

zaterdag 14 december 2024

AxonServer: Table "token_entry" not found

When using AxonServer and you include a @EventHandler in your code, the AxonServer told me that the table "token_entry" was not available.

The problem was that I used Spring-JPA-NHibernate in my code. I defined an entitymanager for JPA and that messed up the entitymanager for Axon. After removing the JPA code and replacing it with jetbrains Exposed, the problem was gone.

An addition setting that I activated was in the application.properties:

spring.jpa.hibernate.ddl-auto=create-drop

You can download the AxonServer at this url: https://download.axoniq.io/axonserver/AxonServer.zip

woensdag 13 november 2024

Browser Debugging in Visual Studio Code made easy.

A couple years ago, it was difficult to setup debugging in Visual Studio Code for browser code. Now it is easy. 

zaterdag 2 november 2024

Using Java build tools

In Java/Kotlin land, Spring is big. See the projects here: https://spring.io/projects

There are two major build systems, Maven and Gradle. Gradle is newer and claims to be the successor, but that remains to be seen.

Using Gradle:
gradlew build
gradlew run
gradlew bootJar

Using Maven:
mvn spring-boot:run
mvn compile
mvn package
mvn clean install

Misc:
To start a spring-boot jar:
java -jar c:\kotlin\demo\target\demo-0.0.1-SNAPSHOT.jar

To start a local webserver:
py -m http.server

Axon:
java -jar axonserver-2024.1.0.jar
mvnw spring-boot:run
localhost:8024 -> webpage axonserver
localhost:8080 -> giftcard sample

Kotlin commandline:
kotlinc hello.kt -include-runtime -d hello.jar
java -jar hello.jar


woensdag 18 september 2024

Fill remaining width using flex

<div class="container">
<div class="flexible">test</div>
<div class="fixed">test</div>
<div class="fixed">test</div>
</div>

.container {
  display: flex;
}

.fixed {
  flex: 0 0 100px;
  background-color: red;
}

.flexible {
  flex: 1
}

zondag 30 juni 2024

How to disable Microsoft Compatibility Telemetry

Microsoft Compatibility Telemetry is a feature that collects data about your computer's performance and usage. It can be helpful for diagnosing problems and improving software compatibility. However, some people may prefer to turn it off for privacy or performance.

1. Click Start, type Task Scheduler, and then press Enter.
2. On the TaskScheduler window, go to this path: Task Scheduler Library\Microsoft\Windows\Application Experience.
3. On the Application Experience folder, look for Microsoft Compatibility Appraiser.
4. Right-click on it, select Disable, and then confirm to complete the process.

maandag 27 mei 2024

Regular expressions in Notepad++

In Notepad, you can search and replace text using regular expressions.
The following expression is non-greedy because the ? is used.
It also creates a group that is used in the replace part.
search:   <span class="t[0-9]*">(.+?)</span>
replace: $1

donderdag 18 april 2024

Postgresql Tips

select * from table
where d.location = 'POINT(0 0)'::geometry
and d.datum < (timestamp 'now' - interval '1 year')

alter table [table] OWNER to [owner]

Grootte van een jsonb rij:
select pg_column_size(datab) from table;


select json_strip_nulls(row_to_json(t))::jsonb - 'columnname_to_skip'
from table t
where t.id = 'id';

maandag 15 april 2024

Always try/catch in a Task.Run in websockets

When you run the following code:

System.Threading.Tasks.Task.Run(() => { throw new Exception(); });
Console.ReadKey();

You will see that the exception is not shown on screen. That's because the task stops within it's own context.
That behaviour is very problematic if the task contains code that sends information over a websocket. The method that contains the Task.Run will probably still be alive, however the task is stopped. The websocket methods will continue, the task will however not send or receive information anymore. In that case you have a websocket which is alive on a network level but dead on a functional level.
To prevent this situation, always use try/catch blocks within the Task.Run.

maandag 26 februari 2024

Everything about windows DLL's

This presentation from CppCon 2017 is really helpful for understanding how DLL's are loaded and functions are exported.

You can read the live debug log from the loader, by setting the SLS on an executable.

gflags /i PrintGreeting.exe +sls
cdb PrintGreeting.exe
gflags /i PrintGreeting.exe -sls

You can export data using:
extern "C" __declspec(dllimport) int const One = 1;
extern "C" __declspec(dllimport) int const Two = 2;

link Constants.obj /dll /out:Constants.dll /noentry /nodefaultlib /export:One,DATA /export:Two,DATA


You can have thread variables using:
Thread local storage:
__declspec(thread) int x = 10;

Dumpbin.exe is more powerful than you might think

dumpbin.exe /exports msvcrt.dll > msvcrt.exports
dumpbin.exe /headers hello.dll
dumpbin.exe /rawdata /section:.text hello.dll
dumpbin.exe /disasm /section:.text hello.dll

dumpbin.exe /dependents PrintGreeting.exe     -> which DLL's are loaded as dependencies
dumpbin.exe /imports PrintGreeting.exe        -> which functions are used in the dependencies

dumpbin.exe /exports hello.lib

MSVCRT.dll will remain in Windows

When creating a small C program, it is necessary to skip the shipping of the C runtime DLL's. Why do you need all those DLL's when you just want to printf something or write a file?

There is only one DLL needed, and that is the old MSVCRT.DLL. This DLL is available since Windows95 or something. It is available on ALL Microsoft Windows systems.

And it is still updated!  I saw an update in August 2023 and October 2023. Why is it still updated? Well it is an KNOWN WINDOWS CORE DLL!

Yes, it is special, even to Microsoft. A lot of system software relies on this DLL and they won't stop shipping the DLL.

There is a list of these special known DLL's. Open the registry editor and go to:

Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs

And in the list with entries like kernel32.dll, ole32.dll, user32.dl and gdi32.dll, you see MSVCRT.dll. Great! Something we can build on.


dinsdag 6 februari 2024

Call Angular method from Javascript

There are situations in which your context becomes javascript and you
need to get back to the Angular context.

Do this with a CustomEvent.

In Javascript do:
function (theDetails){
	var event = new CustomEvent("uniquenamefor.thecustomevent", { 
       detail: theDetails, bubbles: true, cancelable: true
    });    
    window.dispatchEvent(event);
}

This event will be send in the webbrower and we need Anuglar to pick it up.

In Angular do:
import { HostListener, Component } from '@angular/core';

    @HostListener('window:uniquenamefor.thecustomevent', ['$event']) 
    async onUniqueCustomEvent(event) {
    	alert(event.detail);
    }
    
The Angular framework only allows HostListeners on components/directives, so
if you want to catch the CustomEvent in a service you need to resort back
to good old Javascript:
   window.addEventListener('uniquenamefor.thecustomevent', 
       this.onUniqueCustomEvent.bind(this));

maandag 1 januari 2024

C-64: The 16 colors in ARGB

I use these ARGB values as C-64 look-a-like colors for the Ground Compiler:
colors[0] = 0xff000000;  colors[1] = 0xfff1f1f1;
colors[2] = 0xffac4749;  colors[3] = 0xff78d5d0;
colors[4] = 0xffac49c1;  colors[5] = 0xff5dc158;
colors[6] = 0xff4044cb;  colors[7] = 0xffe1e063;
colors[8] = 0xffaf6821;  colors[9] = 0xff7E5500;
colors[10] = 0xffd67d7f; colors[11] = 0xff686868;
colors[12] = 0xff8f8f8f; colors[13] = 0xffa0eb9c;
colors[14] = 0xff8898ff; colors[15] = 0xffb9b9b9;