drupal 6 database layer
DESCRIPTION
TRANSCRIPT
Drupal adatbázis API
Több adatbázis támogatása
● Drupal 6● MySQL: támogatott● PostgreSQL: core támogatja, contribok kevésbé● MSSQL: a Microsoft nagyon szeretné● Oracle: contribként elérhető
● Drupal 7● MySQL: támogatott● PostgreSQL: tesztekkel bizonyítottan támogatott
Könnyűsúlyú API
● Előny● Kevés visszaesés teljesítményben● Könnyen használható
● Hátrány● SQL írásakor nagyon figyelni kell a szintaxisra● Csak olyan funkciókra lehet támaszkodni, amelyek
mindegyik támogatott adatbáziskezelőn elérhetőek
Szintaxis különbség
● Tábla neveket körbe kell venni {}kkel● Értékek helyett placeholderek● Példa
SELECT ”name” FROM {users} WHERE uid = %d
Függvények
db_add_field, db_add_index, db_add_primary_key, db_add_unique_key, db_affected_rows, db_change_field, db_check_setup, db_column_exists, db_connect, db_create_table, db_create_table_sql, db_decode_blob, db_distinct_field, db_drop_field, db_drop_index, db_drop_primary_key, db_drop_table, db_drop_unique_key, db_encode_blob, db_error, db_escape_string, db_escape_table, db_fetch_array, db_fetch_object, db_field_names, db_field_set_default, db_field_set_no_default, db_is_active, db_last_insert_id, db_lock_table, db_placeholders, db_prefix_tables, db_query, db_query_range, db_query_temporary, db_rename_table, db_result, db_rewrite_sql, db_set_active, db_status_report, db_table_exists, db_type_map, db_type_placeholder, db_unlock_tables, db_version, pager_query, tablesort_sql, update_sql
Példák
● Rossz példa:
$res = db_query(”SELECT * FROM {users} WHERE uid = $uid”);
Példák
● Mi van, ha a valahonnan kapott $uid tartalma a következő:
1; UPDATE users SET pass = md5('iamhacked')
Akkor bizony megtörtek :(
Példák
● Az előző példa helyesen
$res = db_query(”SELECT * FROM {users} WHERE uid = %d”, $uid);
● Az uid lehet bármi, a %d miatt numerikus értékké lesz konvertálva.
● Az előző rosszindulatú paraméter esetén 1 lesz.
String
● String használata
$res = db_query(”SELECT uid, name FROM {users} WHERE name = '%s'”, $searchstring);
További típusok
● Float
$res = db_query(”SELECT * FROM {spec_tabla} WHERE valami_mezo > %F”, $float_ertek);
További típusok
● Bináris
$res = db_query(”UPDATE {spec_tabla} SET valami_adat = %b WHERE id = %d”, $binaris_adat, $id);
A % escape-elése
%%
db_query('SELECT nid FROM {node} WHERE title LIKE \'%%%s%%\' ORDER BY nid DESC', $searchstring);
Változó számú érték
$data = array(1, 2, 3);
db_query('SELECT foo FROM {bar} WHERE client_id IN (' . db_placeholders($data, 'int') . ') ORDER BY client_id', $data);
Tábla nevek
db_escape_table()
db_query('SELECT * FROM {' . db_escape_table($table) . '}');
Schema API
Schema API
● Automatikus adatbázisséma generálás● Biztosan adatbázisfüggetlen lesz a kód, amit generál● Könnyebb karbantartani● Könnyen lehet csak egyes részeket felhasználni
hook_schema()
● Használat (.install):
mymodule_schema() {$schema = array(...);
return $schema;
}mymodule_install() {
drupal_install_schema('mymodule');
}
mymodule_uninstall() {
drupal_uninstall_schema('mymodule');
}
Schema tömb
array( 'tablaneve' => array( 'fields' => $fields, 'indexes' => $indexes, 'unique keys' => $unique_keys, 'primary key' => $primary_key, ),);
Mezők
array( 'mezoneve' => array( 'type' => $tipus, 'unsigned' => TRUE, // csak numerikus típussal 'not null' => TRUE, 'length' => $hossz, // nem minden típusnál 'default' => $alapertek, // nem kötelező 'size' => $hossz, // adattípus hossza (nem kötelező),
'precision' => $p, // csak numerikus mezőknél 'scale' => $s, // csak numerikus mezőknél 'serialize' => FALSE, ),);
Típusok
● serial (pg: automatikus sequence, mysql: auto_increment)
● int
● float
● numeric
● varchar
● char
● text
● blob
● datetime
Opciók
● size: az adattípus mérete ('tiny', 'small', 'medium', 'normal', 'big'), lásd: Adattípusok és méreteik
● not null: NULL érték engedélyezése● default: alapértelmezett érték● length: hossz a következő típusoknál: 'varchar',
'text', 'int'● unsigned: 'int', 'float', 'numeric' értékeknél érvényes,
alapértelmezett: FALSE
Opciók
● precision, scale: a 'numeric' típusnál a pontosság (szignifikáns bitek száma)
● serialize: boolean érték, hogy a tárolt adat szerializált sztringe
Kulcsok megadása
● unique keys, indexes:
array('kulcs0' => array('mezo0', 'mezo1'),
'kulcs1' => array('mezo3'),
)
● primary key
array( 'mezo0', 'mezo1' )
API
db_add_field, db_add_index, db_add_primary_key, db_add_unique_key, db_change_field, db_create_table,
db_create_table_sql, db_drop_field, db_drop_index, db_drop_primary_key, db_drop_table, db_drop_unique_key, db_field_names,
db_field_set_default, db_field_set_no_default, db_rename_table, db_type_map, db_type_placeholder, drupal_get_schema, drupal_get_schema_unprocessed,
drupal_install_schema, drupal_schema_fields_sql, drupal_uninstall_schema, drupal_write_record,
_db_create_field_sql, _db_process_field, _drupal_initialize_schema
Táblafrissítés
● function mymodule_update_6001() {$ret = array();
db_add_field($ret, 'mytable1', 'newcol', array('type' => 'int', 'not null' => TRUE));
$schema['mytable2'] = array(...);
db_create_table($ret, 'mytable2', $schema['mytable2']);
db_add_unique_key($ret, 'mytable2', 'mykey', array('field1', 'field2'));
return $ret;
}
További tudnivalók
● Primary key nem lehet NULL● NOT NULL utólagos hozzáadása, alapértelmezett
érték nélkül:
$ret = array();
db_add_field($ret, 'mytable0', 'col1', array('type' => 'text', 'not null' => TRUE, 'initial' => 'start'));
Típusok
Field type PHP types Correct Incorrectint integer 0, 3, 17 0.5, '0'float float 7, 5.75 1.24'numeric float 3.14 2.17'
string '2007-08-26 13:00:00'string '', 'hi mom' 0, 3.14
text N/A noneserial N/A noneblob N/A none
datetime Unix timestampvarchar
JOIN
● A direktszorzat nem hatékony● 3 tábla, 1 millió, fél millió és 50 millió rekorddal
● Hatékony (polinom idejű és memóriaigényű) megoldás: JOIN
JOIN
● (INNER) JOIN
SELECT * FROM foo JOIN bar ON foo.fid = bar.fid
SELECT * FROM foo JOIN bar USING (fid)
● LEFT, RIGHT (OUTER) JOIN
SELECT * FROM foo LEFT JOIN bar ON foo.fid = bar.fid
● NATURAL JOIN
SELECT * FROM foo NATURAL JOIN bar
● http://en.wikipedia.org/wiki/Join_(SQL)
Kompatibilis SQL
● Táblanév köré ” ` helyett● String köré szigorúan '● Adattörlés egyszerre egy táblából● MySQLnél az int és a boolean ugyanaz,
Postgresnél nem!
Kompatibilis SQL
● Kerülni:● IGNORE● REPLACE● ON DUPLICATE KEY
● CONCAT() csak két argumentummal● Minden nem aggregált mezőnek szerepelnie kell a
GROUP BY után● http://drupal.org/node/555514
Kérdések