Az OTRS olyan adatbázis réteggel érkezik, amely különböző adatbázisokat támogat.
Az adatbázis rétegnek (Kernel::System::DB) két bemeneti
lehetősége van: SQL és XML.
Az SQL felületet kell használni a normál adatbázis-műveleteknél (SELECT, INSERT, UPDATE, …). Úgy használható mint egy normál Perl DBI felület.
$Kernel::OM->Get('Kernel::System::DB')->Do(
SQL=> "INSERT INTO table (name, id) VALUES ('Valamilyen név', 123)",
);
$Kernel::OM->Get('Kernel::System::DB')->Do(
SQL=> "UPDATE table SET name = 'Valamilyen név', id = 123",
);
$Kernel::OM->Get('Kernel::System::DB')->Do(
SQL=> "DELETE FROM table WHERE id = 123",
);
my $SQL = "SELECT id FROM table WHERE tn = '123'";
$Kernel::OM->Get('Kernel::System::DB')->Prepare(SQL => $SQL, Limit => 15);
while (my @Row = $Kernel::OM->Get('Kernel::System::DB')->FetchrowArray()) {
$Id = $Row[0];
}
return $Id;
Vigyázzon arra, hogy a Limit megadását paraméterként
használja, és ne az SQL utasításban, mert nem minden adatbázis támogatja a
LIMIT kulcsszót az SQL lekérdezésekben.
my $SQL = "SELECT id FROM table WHERE tn = ? AND group = ?";
$Kernel::OM->Get('Kernel::System::DB')->Prepare(
SQL => $SQL,
Limit => 15,
Bind => [ $Tn, $Group ],
);
while (my @Row = $Kernel::OM->Get('Kernel::System::DB')->FetchrowArray()) {
$Id = $Row[0];
}
return $Id;
Használja a Bind attribútumot, ahol csak tudja, különösen
a hosszú utasításoknál. Ha a Bind attribútumot használja,
akkor nincs szükség a Quote() függvényre.
Szöveg:
my $QuotedString = $Kernel::OM->Get('Kernel::System::DB')->Quote("Ez egy probléma!");
Egész:
my $QuotedInteger = $Kernel::OM->Get('Kernel::System::DB')->Quote('123', 'Integer');
Szám:
my $QuotedNumber = $Kernel::OM->Get('Kernel::System::DB')->Quote('21.35', 'Number');
A Bind attribútumot használja a Quote()
függvény helyett, ahol csak tudja.
Az XML felületet kell használni INSERT, CREATE TABLE, DROP TABLE és ALTER TABLE utasításoknál. Mivel ez a szintaxis adatbázisról adatbázisra eltérő, ezért ennek használata gondoskodik arról, hogy olyan alkalmazásokat írjon, amelyek az összesnél használhatók.
Az <Insert> szintaxis megváltozott a 2.2 és újabb
verziókban. Az értékeket mostantól a címketartalomban használják (többé nem
egy attribútumban).
<Insert Table="some_table">
<Data Key="id">1</Data>
<Data Key="description" Type="Quote">exploit</Data>
</Insert>
A lehetséges adattípusok a következők: BIGINT,
SMALLINT, INTEGER,
VARCHAR (Size=1-1000000), DATE
(Formátum: yyyy-mm-dd hh:mm:ss) és
LONGBLOB.
<TableCreate Name="calendar_event">
<Column Name="id" Required="true" PrimaryKey="true" AutoIncrement="true" Type="BIGINT"/>
<Column Name="title" Required="true" Size="250" Type="VARCHAR"/>
<Column Name="content" Required="false" Size="250" Type="VARCHAR"/>
<Column Name="start_time" Required="true" Type="DATE"/>
<Column Name="end_time" Required="true" Type="DATE"/>
<Column Name="owner_id" Required="true" Type="INTEGER"/>
<Column Name="event_status" Required="true" Size="50" Type="VARCHAR"/>
<Index Name="calendar_event_title">
<IndexColumn Name="title"/>
</Index>
<Unique Name="calendar_event_title">
<UniqueColumn Name="title"/>
</Unique>
<ForeignKey ForeignTable="users">
<Reference Local="owner_id" Foreign="id"/>
</ForeignKey>
</TableCreate>
A LONGBLOB oszlopok különleges bánásmódot igényelnek. A
tartalmukat Base64-re kell átkódolni, ha az
adatbázis-meghajtó nem támogatja a DirectBlob
funkciót. Nézze meg a következő példát:
my $Content = $StorableContent;
if ( !$DBObject->GetDatabaseFunction('DirectBlob') ) {
$Content = MIME::Base64::encode_base64($StorableContent);
}
Hasonlóan, amikor egy ilyen oszlopból olvas, akkor a tartalmat tilos
automatikusan UTF-8-ként visszaalakítani az
Encode => 0 jelző átadásával a
Prepare() függvénynek:
return if !$DBObject->Prepare(
SQL => '
SELECT content_type, content, content_id, content_alternative, disposition, filename
FROM article_data_mime_attachment
WHERE id = ?',
Bind => [ \$AttachmentID ],
Encode => [ 1, 0, 0, 0, 1, 1 ],
);
while ( my @Row = $DBObject->FetchrowArray() ) {
$Data{ContentType} = $Row[0];
# Melléklet visszaalakítása, ha például postgresql háttérprogramot használ.
if ( !$DBObject->GetDatabaseFunction('DirectBlob') ) {
$Data{Content} = decode_base64( $Row[1] );
}
else {
$Data{Content} = $Row[1];
}
$Data{ContentID} = $Row[2] || '';
$Data{ContentAlternative} = $Row[3] || '';
$Data{Disposition} = $Row[4];
$Data{Filename} = $Row[5];
}
A következő az oszlopok hozzáadásának, megváltoztatásának és eldobásának példáját jeleníti meg.
<TableAlter Name="calendar_event">
<ColumnAdd Name="test_name" Type="varchar" Size="20" Required="true"/>
<ColumnChange NameOld="test_name" NameNew="test_title" Type="varchar" Size="30" Required="true"/>
<ColumnChange NameOld="test_title" NameNew="test_title" Type="varchar" Size="100" Required="false"/>
<ColumnDrop Name="test_title"/>
<IndexCreate Name="index_test3">
<IndexColumn Name="test3"/>
</IndexCreate>
<IndexDrop Name="index_test3"/>
<UniqueCreate Name="uniq_test3">
<UniqueColumn Name="test3"/>
</UniqueCreate>
<UniqueDrop Name="uniq_test3"/>
</TableAlter>
A következő egy olyan példát jelenít meg, hogy hogyan nevezhető át egy tábla.
<TableAlter NameOld="calendar_event" NameNew="calendar_event_new"/>
my @XMLARRAY = @{$Self->ParseXML(String => $XML)};
my @SQL = $Kernel::OM->Get('Kernel::System::DB')->SQLProcessor(
Database => \@XMLARRAY,
);
push(@SQL, $Kernel::OM->Get('Kernel::System::DB')->SQLProcessorPost());
for (@SQL) {
$Kernel::OM->Get('Kernel::System::DB')->Do(SQL => $_);
}