Thứ Ba, 6 tháng 8, 2013

Drupal nâng cao - 2. Working with Database


LÀM VIỆC VỚI DATABASE TRONG DRUPAL

posted 25 Jun 2013 01:40 by Nam Minh
1. DATABASE ABSTRACTION LAYER.
+ Drupal sẽ biết database nào dùng để kết nối và username, password cần để thiết lập kết nối với database bằng cách tìm kiếm trong file settting.php. File này đặc thù sẽ nằm ở drupal\sites\default. Dòng định nghĩa kết nối với database như sau :
Code: Chọn hết
$db_url = 'mysql://username:password@localhost/databasename';
+ Đã bao giờ bạn có một project và bạn cần thay đổi hệ thống database, bạn phải bỏ ra rất nhiều thời gian để chỉnh sửa code? Với database abstraction layer, bạn sẽ ko còn phải làm những công việc này, ví dụ : khi chuyển từ MySQL sang PostgreSQL bạn sẽ phải thay đổi mysql_quer() thành pg_query(), Drupal sẽ sử dụng db_query() và bạn không cần quan tâm đến hệ thống database đang sử dụng nữa.
+ Lớp Database abstraction được đưa ra với 2 mục đích chính :
- Giúp cho code của bạn tương thích với bất kỳ hệ thống database nào.
- Ngăn chặn các cuộc tấn công bằng lỗi SQL-injection.
+ Drupal xác định kiểu database để kết nối thông qua biến $db_url bên trong file setting.php. Ví dụ : nếu biến $db_url bắt đầu với mysql, Drupal sẽ include file includes/database.mysql.inc, nếu nó bắt đầu với pgsql Drupal sẽ include file includes/database.pgsql.inc
Hình ảnh
2. THỰC HIỆN TRUY VẤN
+ Drupal sẽ tự động kết nối với database và bạn sẽ không cần phải lo lắng về điều này.
+ Hàm db_query() của Drupal thường được dùng để để truy vấn với kết nối database đã active. Những truy vấn này bao gồm SELECT, UPDATE, INSERT và DELETE.
+ Ví dụ : lấy tất cả các dòng và các fields của bảng joke với field vid và nó cùng trị với $node->vid :
Code: Chọn hết
db_query('SELECT * FROM {joke} WHERE vid = %d', $node->vid);
+ Thêm vào 1 dòng :
Code: Chọn hết
db_query("INSERT INTO {joke} (nid, vid, punchline) VALUES (%d, %d, '%s')",
$node->nid, $node->vid, $node->punchline);
+ Cập nhật :
Code: Chọn hết
db_query("UPDATE {joke} SET punchline = '%s' WHERE vid = %d", $node->punchline,
$node->vid);
+ Xóa :
Code: Chọn hết
db_query('DELETE FROM {joke} WHERE nid = %d', $node->nid);
+ Đây là những cú pháp của Drupal mà bạn cần biết khi viết câu truy vấn SQL. Sau đây là bản tham số của Drupal SQL :
Hình ảnh
+ Tham số đầu tiên của db_query() luôn luôn là câu truy vấn, những cái còn lại là những giá trị động, nó sẽ được validate và thêm vào câu truy vấn.
3. NHÂN KẾT QUẢ TRUY VẤN.
+ Có nhiều cách để nhận kết quả truy vấn, phụ thuộc vào việc bạn cần 1 dòng hay toàn bộ tập kết quả hoặc bạn cũng có thể mở rộng kết quả.
+ Để lấy một giá trị đơn :
Code: Chọn hết
$sql = "SELECT COUNT(*) FROM {node} WHERE type = 'blog' AND status = 1";
$total = db_result(db_query($sql));
+ Để lấy nhiều dòng :
Code: Chọn hết
$sql = "SELECT * FROM {node} WHERE type = 'blog' AND status = 1";
$result = db_query(db_rewrite_sql($sql));
while ($data = db_fetch_object($result)) {
$node = node_load($data->nid);
print node_view($node, TRUE);
}
+ Lấy kết quả có giới hạn :
Code: Chọn hết
$sql = "SELECT * FROM {node} n WHERE type = 'blog' AND status = 1 ORDER BY
n.created DESC";
$result = db_query_range(db_rewrite_sql($sql), 0, 10);
Thay vì sử dụng từ khóa LIMIT trong câu truy cấn, chúng ta lại dùng db_query_range(). Tại sao lại dùng như vậy? Bởi vì không phải tất cả các hệ quản trị dữ liệu đều cung cấp từ khóa LIMIT.
+ Lấy kết quả để thể hiện thành trang (kĩ thuật dàn trang) :
Code: Chọn hết
$sql = "SELECT * FROM {node} n WHERE type = 'blog' AND status = 1 ORDER BY n.created DESC"
$result = pager_query(db_rewrite_sql($sql), 0, 10);
while ($data = db_fetch_object($result)) {
$node = node_load($data->nid);
print node_view($node, TRUE);
}
// Add links to remaining pages of results.
print theme('pager', NULL, 10);.
Hàm theme('pager') sẽ hiện thị các link đến các trang khác.
4. SỬ DỤNG BẢNG TEMPORARY
+ Nếu bạn làm việc với nhiều tiến trình, bạn có thể tạo bản Temporary (bảng tạm) trong suốt quá trình truy vấn. Bạn có thể dùng hàm db_query_temporary() với cú pháp như sau :
Code: Chọn hết
$result = db_query_temporary($sql, $arguments,
$temporary_table_name);
+ Sau khi tạo bảng temporary, bạn có thể dùng nó. Ví dụ: trong hàm do_search() của module Search, việc tìm kiếm được thực hiện qua nhiều giai đoạn bằng cách dùng các bảng tạm để lưu trữ thông tin trung gian :
Code: Chọn hết
// Select initial search results into temporary table named 'temp_search_sids'.
$result = db_query_temporary("
SELECT i.type, i.sid, SUM(i.score * t.count) AS relevance, COUNT(*) AS matches
FROM {search_index} i
INNER JOIN {search_total} t ON i.word = t.word $join1
WHERE $conditions
GROUP BY i.type, i.sid
HAVING COUNT(*) >= %d",
$arguments, 'temp_search_sids');
...
// Later: calculate maximum relevance, to normalize it, using temporary table.
$normalize = db_result(db_query('SELECT MAX(relevance) FROM temp_search_sids'));
...
// Still later: create a temporary search results table named 'temp_search_results'.
$result = db_query_temporary("
SELECT i.type, i.sid, $select2
FROM temp_search_sids i
INNER JOIN {search_dataset} d
ON i.sid = d.sid AND i.type = d.type $join2
WHERE $conditions $sort_parameters",
$arguments, 'temp_search_results');
...
// Finally: do actual search query.
$result = pager_query("SELECT * FROM temp_search_results", 10, 0, $count_query);
5. ĐẶT CÁC CÂU TRUY VẤN VÀO CÁC MODULE KHÁC VỚI HOOK_DB_REWRITE_SQL().
+ Các hook dùng để thay đổi các câu truy vấn được tạo ra ở một nơi khác trong Drupal để bạn không phải thay đổi các module một các trực tiếp.
+ Nếu bạn gởi một câu truy vấn đến hàm db_query() và bạn nghĩ rằng những người khác muốn thay đổi nó, bạn nên sử dụng db_rewrite_sql() để làm cho câu truy vấn có thể được tương tác bởi những người phát triển khác.
+ Khi một câu truy vấn được thực thi, đầu tiên nó sẽ kiểm tra xem tất cả các module có cài đặt hook db_rewrite_sql hay không, nếu có nó sẽ đưa cho chúng thay đổi câu query.
+ Ví dụ : module node sẽ thay đổi các câu truy vấn để liệt kê danh sách các node và ngăn chặn các node đã được bảo vệ bởi accsess rule.
+ Nếu bạn không đưa ra các câu truy vấn và muốn module của mình có thể thay đổi các câu truy vấn khác, bạn hãy cài đặt hook này trong module của bạn.
+ Để ghi đè các câu truy vấn :
Code: Chọn hết
function hook_db_rewrite_sql($query, $primary_table = 'n',
$primary_field = 'nid',$args = array())

Không có nhận xét nào:

Đăng nhận xét