Bridgetown-basierende Internetauftritte können auf Inhalte der NoSQL-Datenbank ArcadeDB zugreifen.

Setup für eine Ruby-Anwendung
Gemfile
Skript
require 'arcade'
require 'arcarde-time-graph'
Arcade::Init.connect
DB = Arcade::Init.db
# test
DB.hierarchy
ArcadeDB ist eine universale NoSQL-Datenbank. »NoSQL« steht für »Not Only SQL«. Die Datenbank ist eine Alternative zu klassischen rationalen Datenbanken.
Die Daten sind entweder als Graphen angelegt, werden über Schlüssel abgespeichert (Key/Value) oder als lose strukturierte Dokumente. Die Datenbank verwendet Standardprotokolle für die Datenzugriffe.
Über das Plugin können mit Bridgetown verwaltete Webinhalte auf Datenbankinhalte zugreifen. Im statischen Modus liest das Framework die Daten bei der Erstellung der Webseiten aus der Datenbank. Die Internetseite selbst ist weiterhin statisch. Wenn sich der Datenbankinhalt ändert, muss die Webseite neu erstellt werden.
Im SSR-Modus wird die Datenbank bei jedem Aufruf der Webseite erneut abgefragt und die Webseite dynamisch erstellt.
Das Plugin verwendet das ArcadeDB-Gem für den Datenbankzugriff.
Initialisierung
Die Integration gelingt mit wenigen Befehlen
- Im
Gemfile
werden die Bibliothekenarcadedb
und (optional)arcade-time-graph
eingebunden, zusätzlich das Plugingem 'arcadedb' gem 'arcade-time-graph' gem 'bridgetown-arcade-db'
- In der
config/initialisers.rb
wird mindestens das arcade-db-Plugin aktiviert. Für die Wiedergabe dynamischer Inhalte wird zusätzlichssr
undbridgetown-routes
benötigt.
init :ssr
init :"bridgetown-routes"
init :"bridgetown-arcade-db"
Der Initializer
Beim Start liest Bridgetown die Datei config/initializers
ein und führt die
dort verzeichneten Befehle aus.
Das Ruby-Symbol :"bridgetown-arcade-db"
zieht den Aufruf von Bridgetown.initializer
mit dem
Argument :bridgtown-arcade-db
nach sich. Das Plugin ist im Kern das Ergebnis der Ausführung dieser
Methode.
Bridgetown.initializer :"bridgetown-arcade-db" do |config|
BridgetownArcadeDb.load_models config
Arcade.const_set :ProjectRoot, Pathname.new( config.root_dir )
Arcade::Init.connect Bridgetown.environment
end
- Zuerst werden über
load_models
Datenbank-Model-Dateien eingebunden. Diese werden üblicherwiese unterhalb des Verzeichnisses/model
angelegt. - Dem Arcade-Gem muss danach mitgeteilt werden, wo es diese Dateien finden kann. Dazu wird das ProjektRoot gesetzt.
- Abschließend ruft der Initializer die
connect
-Methode auf. Welche Datenbank geöffnet werden soll, wird ausconfig/arcade.yml
eingelesen.
--- #/config/arcade.yml
:environment:
:test:
dbname: test
user: root
pass: ****
:development:
dbname: playground
user: root
pass: ****
:production:
dbname: bridgetown
user: root
pass: ****
:admin:
:host: localhost
:port: 2480
:user: root
:pass: ****
:modeldir: model
:logger: stdout # 'file' or 'stdout'
:namespace: Arcade
Für die unterschiedlichen Umgebungen können unterschiedliche Datenbanken angegeben werden, die von unterschiedlichen Nutzern mit angepassten Zugriffsrechten genutzt werden. Die Angabe des Namespaces ist für die Modelfiles relevant.
Modelfiles
Die Datenbank ist hoch flexibel und kann weitgehend mit adhoc-Daten gefüllt werden. Trotzdem müssen die Datanbanktabellen selbst als Modelfile definiert werden.
Hier ein Beispiel für die Definition einer Person
module Arcade
class Person
attribute :name, Types::Nominal::String
attribute :surname, Types::Nominal::String.default( "".freeze )
attribute :email?, Types::Email
attribute :age?, Types::Nominal::Integer
attribute :active, Types::Nominal::Bool.default( true )
attribute :conterfeil?, Types::Nominal::Any
def self.db_init
File.read(__FILE__).gsub(/.*__END__/m, '')
end
end
end
## The code below is executed on the database after the database-type is created
## Use the output of `ModelClass.database_name` as DB type name
##
__END__
CREATE PROPERTY user.name STRING
CREATE PROPERTY user.surname STRING
CREATE PROPERTY user.email STRING
CREATE INDEX ON user ( name ) NOTUNIQUE
CREATE INDEX ON user ( name, surname, email ) UNIQUE
Die Definitionen sind weitgehend selbsterklärend. Attribute mit einem Fragezeichen sind optional. Die Daten sind streng typisiert, das ist Voraussetzung für einen konsistenten Datenbankaufbau.
Adhoc Datenbank
Zusätzlich zu den definierten Datenbankfeldern können weitere, untypisierte Felder angelegt werden.
So können dynamisch unidirektionale Abhängigkeiten adhoc dargestellt werden:
Person.create name: 'Hugo', surname: 'Gans'
father: Person.create( name: 'Otto', surname: 'Gans' ),
children: [ "Eva", "Ulli", "Uwe", "Georg" ].map{ |c| Person.create( name: c, surname: 'Gans' ) }
Diese Anweisung legt father
und children
-Felder an und füllt sie mit Personen. Die Ausgabe des Datensatzes
zeigt die angelegten Personen in Form ihrer Datenbank-Identitäten.
puts hugo.to_human
<person[#187:0]: {->}{->}}, active: true,
children: ["#175:0", "#178:0", "#181:0", "#184:0"],
father: <person[#172:0]: active : true, name : Otto, surname : Gans>,
name: Hugo, surname: Gans>
puts hugo.children.map &:expand
<person[#175:0]: active : true, name : Eva, surname : Gans>
<person[#178:0]: active : true, name : Ulli, surname : Gans>
<person[#181:0]: active : true, name : Uwe, surname : Gans>
<person[#184:0]: active : true, name : Georg, surname : Gans>