Wednesday 12 October 2022

How to install Synology Desktop Utilities on non-Debian Linux Systems

For Linux Desktop users with a Synology NAS, it is nice to use their Deskop Tooling. Unfortunately, Synology abandoned Support for .rpm based systems and only supports Debian's .deb format. Now these tools are not a must-use. Note Station can be used via the web front end and syncing could be done with any native Linux solution that you like. But if you want the ease of their tools, here is a possible solution.

UPDATE: since the Synology Drive Client is available via Flathub, I added this as the easiest option.

I have done this on OpenSUSE Tumbleweed, but this should work on any other .rpm based system.

1. The easiest way: Synology Drive Client from Flathub

On a KDE Plasma system like Tumbleweed or Manjaro, open Discover and add Flathub to your sources:

Search for Synology and install Synology Drive

As Flakpaks have limited system access by design, you need to configure Synology Drive to have file system access. The easiest way to do this is via another Flatpak app, search for Flatseal and install it.
Open Flatseal, select Synolgy Drive and grant it access to all directories you want to sync 
Start Synology Drive and use it as usual
This solution has a drawback at least on my installation on OpenSUSE Tumbleweed with KDE: it only runs with X11, not with Plasma. If this happens to you, try the next solution.

2. The (somewhat) easy way: Synology Drive Client

If you can not or don't want to use Flakpaks, then try this solution:

Alien is your friend, so get any of the alien packages from software.opensuse.org, download the .deb version of Synology Drive Client, use alien on it and just install the newly created .rpm (in my case synology-drive-7.0.2-12683.x86_64.rpm).

The tricky part was to get alien up and running. Alien requires rpm-build, which requires the patch utility. Tumbleweed comes with an older version of patch that comes with mingw, but rpm-build requires a newer one. So uninstall patch and install Gnu patch, then install rpm-build, then alien.

sudo alien -r synology-drive-client-12682.x86_64.deb
sudo zypper in synology-drive-7.0.2-12683.x86_64.rpm

Install it with zypper and you are done, this should also run on KDE Plasma.

Everything works, it also starts automatically on login.

3. The hard way: Synology Note Station Client

Ideally, the above way should work with any of the Synology Tools. But doing so completely messed up my KDE Plasma environment. Right after the zypper install command, my did not react to any input anymore. After restart, I did not boot to the login screen, but was stuck on a dark grey screen with a mouse pointer. Instead of repairing, I quickly reinstalled Tumbleweed and tried it again. Same problem again, I can reproduce this at will. I did not had the time to fix this, so I reinstalled Tumbleweed again. Here is the workaround that I used:

sudo alien -g synology-note-station-client-2.2.1-553-linux-x64.deb

Again, use alien, but this time use the -g option to just unpack the .rpm to a directory structure.

This gives you a directory structure, that just needs to be copied to the corresponding directories ...

cd synology-drive-client-12682.x86_64
sudo cp -R * /

and that's it.

That works fine, I haven't had any issues until now.


Tuesday 11 October 2022

Use SQL PIVOT to display a pivot table in Apex #JoelKallmanDay

In a project, we had the question on how we can visualize a pivot table in Apex. We have locations with warehouses, which we want to display as rows. In the columns, we needed the quantity of each stock item.

So our simple data model is:

To query all items with their stock, we use

select loc_id, loc_name, sto_quantity, item_name
from location, stock, item
where sto_loc_id_fk = loc_id
and sto_item_id_fk = item_id

Using this statement for an Interactive Report in Apex gives the following output:


We have several lines for the same item, eg. Tire B in Frankfurt. So we need to sum up per item and location.
Apex does not have a native feature to make a pivot table from this data, as this is already implemented with the SQL PIVOT. The following statement gives us a row for every location and a colum for every items stock

select * from (
select loc_id, loc_name, sto_quantity, item_name
from location, stock, item
where sto_loc_id_fk = loc_id
and sto_item_id_fk = item_id
)
pivot( sum(sto_quantity) as quantity for item_name 
    in ('Tire A' as Tire_A, 'Tire B' as Tire_B, 'Tire C' as Tire_C,
        'Screw A' as Screw_A, 'Screw B' as Screw_B, 'Screw C' as Screw_C)
);

Using this as a source for another Interactive Report gives us the required pivot view

Easy as that. If you want to try yourself, here is the SQL code to create the tables and some test data.

drop table location;
drop table stock;
drop table item;

create table location (
    loc_id                         number generated by default on null as identity 
                                   constraint location_loc_id_pk primary key,
    loc_name                       varchar2(30 char)
)
;

create table stock (
    sto_id                         number generated by default on null as identity 
                                   constraint stock_sto_id_pk primary key,
    sto_loc_id_fk                number,
    sto_item_id_fk                     number,
    sto_quantity                   number
)
;

create table item (
    item_id                        number generated by default on null as identity 
                                   constraint item_item_id_pk primary key,
    item_name                      varchar2(30 char)
)
;


create or replace procedure create_stock_data as 
    type vc_list is table of varchar2(32) 
        index by pls_integer;
    loc_list    vc_list;
    item_list   vc_list;
begin

    loc_list := vc_list('Frankfurt','Hannover','Berlin','Regensburg','Elmshorn','Bensheim');
    
    for idx in indices of loc_list loop
        dbms_output.put_line( idx || ': ' || loc_list(idx) );
        insert  into location
                (loc_id, loc_name)
        values  (idx, loc_list(idx) );
    end loop;
    
    item_list := vc_list('Tire A', 'Tire B', 'Tire C','Screw A','Screw B','Screw C');  
    
    for idx in indices of loc_list loop
        dbms_output.put_line( idx || ': ' || item_list(idx) );
        insert  into item
                (item_id, item_name)
        values  (idx, item_list(idx) );
    end loop;   

    for i in 1..100 loop
      dbms_output.put_line(i);
      insert   into stock
               (sto_id, sto_loc_id_fk, sto_item_id_fk, sto_quantity)
      values   (i, round(dbms_random.value(1,6)), round(dbms_random.value(1,6)), round(dbms_random.value(1,100)) );
    end loop;

end create_stock_data;
/