Hydrogen-Pattern-Creator 4.0 - Entwicklung, Weiterschritt

Hydrogen-Pattern-Creator 4.0


Noch laufen die Vorarbeiten, aber es sieht schon sehr gut aus!

Die neue Produktlinie soll eine Postgres-Datenbank nutzen. Diese soll den Namen "emysuk" tragen. Folglich muß ich sie neu anlegen. Das geschieht so:
sudo -u postgres createdb -O NUTZERNAME DATENBANK
PostgreSQL › Wiki › ubuntuusers.de
Nach entsprechenden Einsetzungen in NUTZERNAME und DATENBANK existiert diese nun wie gewünscht.

Nun möchte ich, daß neu erstellte bzw. überarbeitete/gecheckte Pattern durch Abspeichern des Songs (den der Pattern-Creator vorher erzeugt hat) und nachfolgender Programmbearbeitung in eine temporäre Tabelle in der emysuk-Datenbank gespeichert werden.

Code-Schnippsel

...
# Pattern in die E-Mysuk-Datenbank schreiben

connect_emysukdb();
pattern_temp_create();
disconnect_emysukdb();
...
###############################################################
#### Datenbank-Handling ####
###############################################################


# Subroutinen Verbindung


sub connect_emysukdb {
    ## Verbindung zur DB herstellen
    $dbh = DBI->connect("DBI:Pg:dbname=emysuk;host=localhost", "$DB_USER", "$DB_PASSWD");
}

sub disconnect_emysukdb {
    $dbh->disconnect();
}


# Pattern in emysuk-DB speichern

## Temporäre Tabelle pattern_temp erzeugen

sub pattern_temp_create {
    my $pattern_temp_create = 'CREATE TABLE IF NOT EXISTS pattern_temp
                               ( pattern_id INT PRIMARY KEY UNIQUE,
                                 pattern TEXT,
                                 soundbank TEXT );';
    $dbh->do($pattern_temp_create) or print $dbh->errstr;
}

So. Funzt.

Nun noch kurz den Insert entwerfen (ich schreibe das deshalb wieder peu ´a` peu, weil ich eine längere Pause in Sachen PostgreSQL hinter mir habe; nach diesem Einstieg werde ich wieder einsilbiger, ich versprech's!):

Mir ist eingefallen, daß ich kenntlich machen sollte, wozu die Pattern gehören:

...
# Pattern in emysuk-DB speichern

## Temporäre Tabelle pattern_temp erzeugen

sub pattern_temp_create {
    my $pattern_temp_create = 'CREATE TABLE IF NOT EXISTS hydrogen_pattern_temp
                               ( pattern_id INT PRIMARY KEY UNIQUE,
                                 pattern TEXT,
                                 soundbank TEXT );';
    $dbh->do($pattern_temp_create) or print $dbh->errstr;
}

## Insert-Statement

sub pattern_insert {
    my $pattern = shift;
    my $soundbank = shift;
    my $pattern_insert = $dbh->prepare("INSERT INTO hydrogen_pattern_temp (pattern, soundbank)
                                        VALUES (?,?) ON CONFLICT (pattern) DO NOTHING;");
    $pattern_insert->execute($pattern,$soundbank) or print $dbh->errstr;
    print "\nDie Hydrogen-Pattern wurden in eine temporäre Tabelle der DB emysuk übergeben!\n";
}
...
Die emysuk-DB soll ja auch Midi-Pattern für MuseScore etc. in Zukunft enthalten & verwalten.

...
# Pattern in die E-Mysuk-Datenbank schreiben

## DB-Connect & Temp-Table-Create

connect_emysukdb();
pattern_temp_create();

## Die einzelnen Pattern übergeben & DB-Disconnect

foreach ( @patterns ) {
    pattern_insert($_,$soundbank)
}

disconnect_emysukdb();
...
...

atching the ON CONFLICT specification at hydrogen-patternwriter_4.minus1.pl line 339.
ERROR:  there is no unique or exclusion constraint matching the ON CONFLICT specification
Die Hydrogen-Pattern wurden in eine temporäre Tabelle der DB emysuk übergeben!
DBD::Pg::st execute failed: ERROR:  there is no unique or exclusion constraint matching the ON CONFLICT specification at hydrogen-patternwriter_4.minus1.pl line 339.
ERROR:  there is no unique or exclusion constraint matching the ON CONFLICT specification
Die Hydrogen-Pattern wurden in eine temporäre Tabelle der DB emysuk übergeben!

Stimmt ja! Da ist noch kein Unique- oder Exclusion-Constraint angelegt.

    my $pattern_temp_create = 'CREATE TABLE IF NOT EXISTS hydrogen_pattern_temp
                               ( pattern_id INT PRIMARY KEY UNIQUE,
                                 pattern TEXT UNIQUE,
                                 soundbank TEXT );';
...

ERROR:  null value in column "pattern_id" violates not-null constraint
DETAIL:  Failing row contains (null, {"  <pattern>
","   <name>random-pattern-11.3.3-39</name>
","   ..., Forzee Stereo Drumkit Gain 0,5).
Die Hydrogen-Pattern wurden in eine temporäre Tabelle der DB emysuk übergeben!
DBD::Pg::st execute failed: ERROR:  null value in column "pattern_id" violates not-null constraint
DETAIL:  Failing row contains (null, {"  <pattern>
","   <name>random-pattern-11.3.3-40</name>
","   ..., Forzee Stereo Drumkit Gain 0,5). at hydrogen-patternwriter_4.minus1.pl line 339.
ERROR:  null value in column "pattern_id" violates not-null constraint
DETAIL:  Failing row contains (null, {"  <pattern>
","   <name>random-pattern-11.3.3-40</name>
","   ..., Forzee Stereo Drumkit Gain 0,5).
Die Hydrogen-Pattern wurden in eine temporäre Tabelle der DB emysuk übergeben!
Ach, es fehlt noch etwas. Bzw., es darf etwas fehlen:

sub pattern_temp_create {
    my $pattern_temp_create = 'CREATE TABLE IF NOT EXISTS hydrogen_pattern_temp
                               ( pattern TEXT UNIQUE,
                                 soundbank TEXT );';
    $dbh->do($pattern_temp_create) or print $dbh->errstr;
}

An dieser Stelle brauche ich keinerlei Nummerierung oder IDierung der wenigen Pattern, die nur zwischengeparkt werden, um dann unter ID-Vergabe in eine feste Tabelle übernommen zu werden.

...

Die Hydrogen-Pattern wurden in eine temporäre Tabelle der DB emysuk übergeben!

Die Hydrogen-Pattern wurden in eine temporäre Tabelle der DB emysuk übergeben!

Die Hydrogen-Pattern wurden in eine temporäre Tabelle der DB emysuk übergeben!

Die Hydrogen-Pattern wurden in eine temporäre Tabelle der DB emysuk übergeben!

Die Hydrogen-Pattern wurden in eine temporäre Tabelle der DB emysuk übergeben!

Der Ausdruck ist noch inperfekt, ansonsten:

SELECT pattern, soundbank
  FROM public.hydrogen_pattern_temp;
Total query runtime: 344 msec
35 Zeilen geholt.
...

Nach ein paar wenigen Holpern ist es nun so gut wie perfekt, so:

...

# Pattern in die E-Mysuk-Datenbank schreiben

## DB-Connect & Temp-Table-Create

connect_emysukdb();
pattern_temp_create();

## Die einzelnen Pattern übergeben & DB-Disconnect

foreach ( @patterns ) {
    my $pattern = join("",@$_);
    pattern_insert($pattern,$soundbank)
}

disconnect_emysukdb();

...

###############################################################
#### Datenbank-Handling ####
###############################################################


# Subroutinen Verbindung


sub connect_emysukdb {
    ## Verbindung zur DB herstellen
    $dbh = DBI->connect("DBI:Pg:dbname=emysuk;host=localhost", "$DB_USER", "$DB_PASSWD");
}

sub disconnect_emysukdb {
    $dbh->disconnect();
}


# Pattern in emysuk-DB speichern

## Temporäre Tabelle pattern_temp erzeugen

sub pattern_temp_create {
    my $pattern_temp_create = 'CREATE TABLE IF NOT EXISTS hydrogen_pattern_temp
                               ( pattern TEXT UNIQUE,
                                 soundbank TEXT );';
    $dbh->do($pattern_temp_create) or print $dbh->errstr;
}

## Insert-Statement

sub pattern_insert {
    my $pattern = shift;
    my $soundbank = shift;
    $pattern = encode('UTF-8', $pattern, Encode::FB_CROAK);
    $soundbank = encode('UTF-8', $soundbank, Encode::FB_CROAK);
    my $pattern_insert = $dbh->prepare("INSERT INTO hydrogen_pattern_temp (pattern, soundbank)
                                        VALUES (?,?) ON CONFLICT (pattern) DO NOTHING;");
    $pattern_insert->execute($pattern,$soundbank) or print $dbh->errstr;
    print "\nDas Hydrogen-Pattern wurden in eine temporäre Tabelle der DB emysuk übergeben!\n";
}

...


Zur Sicherheit selecte ich nochmal in eine Textdatei:

SELECT pattern, soundbank
  FROM public.hydrogen_pattern_temp;

...
     <pan_L>0.5</pan_L>
     <pan_R>0.5</pan_R>
     <pitch>0</pitch>
     <key>C0</key>
     <length>-1</length>
     <instrument>19</instrument>
     <note_off>false</note_off>
    </note>
    <note>
     <position>144</position>
     <leadlag>0</leadlag>
     <velocity>0.8</velocity>
     <pan_L>0.5</pan_L>
     <pan_R>0.5</pan_R>
     <pitch>0</pitch>
     <key>C0</key>
     <length>-1</length>
     <instrument>19</instrument>
     <note_off>false</note_off>
    </note>
    <note>
     <position>144</position>
     <leadlag>0</leadlag>
     <velocity>0.8</velocity>
     <pan_L>0.5</pan_L>
     <pan_R>0.5</pan_R>
     <pitch>0</pitch>
     <key>C0</key>
     <length>-1</length>
     <instrument>19</instrument>
     <note_off>false</note_off>
    </note>
   </noteList>
  </pattern>
";"Forzee Stereo Drumkit Gain 0,5"
Alles paletti!

Nein, ganz wichtig!!

...
     <note_off>false</note_off>
    </note>
   </noteList>
  </pattern>
";"Forzee Stereo Drumkit Gain 0,5"
"  <pattern>
   <name>random-pattern-11.3.3-40</name>
   <category>No category</category>
   <size>192</size>
   <noteList>
    <note>
     <position>0</position>
     <leadlag>0</leadlag>
     <velocity>0.8</velocity>
...

Der Pattern-Name muß natürlich verschwinden, sonst können Dubletten übersehen werden!

...

foreach ( @pattern_lines ) {
    if ( $_ =~ /<pattern>/ ) { $pattern_toggle = 1 }
    if ( $pattern_toggle == 1 ) {
        $_ =~ s/<name>(.*)<\/name>/<name>leer<\/name>/;
        push @pattern_lines_temp, $_
    }
    if ( $_ =~ /<\/pattern>/ ) { $pattern_toggle = 0 }
    my $scalplt = scalar @pattern_lines_temp;
    if ( $pattern_toggle == 0 && $scalplt > 0 ) {
        push @patterns, [@pattern_lines_temp];
        @pattern_lines_temp = ();
    }
}

...


Sollte eigentlich funzen.

...
     <instrument>14</instrument>
     <note_off>false</note_off>
    </note>
   </noteList>
  </pattern>
";"Forzee Stereo Drumkit Gain 0,5"
"  <pattern>
   <name>leer</name>
   <category>No category</category>
   <size>192</size>
   <noteList>
    <note>
     <position>0</position>
     <leadlag>0</leadlag>
     <velocity>0.8</velocity>

...

Klappt. Somit eine kurze Pause und die nächsten Schritte können folgen.

Kommentare

Beliebte Posts aus diesem Blog

·

Es brennt.

Bye, bye Nord Stream 2!