+1

[Javascript] Indexed Database P.2

Ở lần trước mình có giới thiệu về [Javascript] Indexed Database hôm nay mình sẽ tiếp tục phần 2 của Indexed Database.

Access vào DB

Mình bổ sung thêm 1 chút về phần Access . ở phần trước mình có nói là parameter thứ 2 đó là name version version là 1 số nguyên lớn hơn 1. với name version này thì chúng ta sẽ chỉnh định version được mở lên khi chúng ta truy cập vào trong DB.

Tuy nhiên nếu trường hợp chúng ta nhập parameter name version với giá trị là nhỏ hơn version hiện tại thì APP sẽ không tương thích với DB mới và sẽ có thể dẫn đến sự cố xảy ra, dẫn đến không thể mở DB lên được.

Câu hỏi đặt ra là giả sử trường hợp chúng ta muốn nâng cấp version của DB thì làm như thế nào ? . câu trả lời rất đơn giản đó là khi mà open thì chúng ta chỉ việc truyền parametter version cao hơn version hiện tại thì APP sẽ hiểu và tự động nâng cấp version hiện tại lên.

Có nghĩa là khi mà chúng ta muốn update thay đổi Spec của DB thì ở trong method open chỉ cần truyền vào số cao hơn version hiện tại của DB là được và nó sẽ tự động tạo mới version của DB cũng như chuyển đến phần version của DB đó.

Nhân tiện thì với phần parameter version chúng ta có thể hoàn toàn lược bỏ đi. khi chúng ta thực hiện mở DB theo cách thông thường thì đương nhiên version của DB sẽ không được nâng lên. có nghĩa là chúng ta sẽ mở và thao tác trên DB với version hiện tại. tuy nhiên theo quan điểm cá nhân của mình thì không nên lược bỏ version đi. mà cứ cho vào cho chắc củ.

Với phần nâng cấp phiên bản version thì mình sẽ trình bày chi tiết hơn nữa ở phần sau.

Bây giờ trường hợp chúng ta đã mở được DB lên 1 cách bình thường. thì properties result của IDBOpenDBRequest được đưa vào instant object của IDBDatabase. instant object của IDBDatabase thì nó là object và trở thành cổng vào thao tác với DB .

Sau đây chúng ta sẽ thực hiện thao tác open DB

var request = indexedDB.open("test",1); // mở DB có tên là test với version chỉ định là 1 。giá trị trả là của method open là IDBOpenDBRequest
// Handle event khi mà thành công 
request.addEventListener("success",function(e){
  console.log(request.result);	//result chứa 1 object IDBDatabase
});
//Handle event khi mà thất bại.
request.addEventListener("error",function(e){
  console.error(request.error);
});

ở ví dụ chúng ta thực thi mở DB và Object IDBDatabase sẽ được hiển thị trên phần cosole.

Trước khi đi đến phần thao tác với DB thì mình sẽ giới thiệu luôn phần deleteDatabase . việc deleteDatabase thì rất đơn giản đó là chúng ta chỉ cần truyền tên của database là xong. Với giá trị trả về thì giống như method open thfi sẽ trả về ở IDBOpenDBRequest. và sẽ phát sinh 2 event là success hoặc error . thêm nữa nếu mà DB đang xử lí mà chúng ta thực hiện xóa thì . việc xóa sẽ chờ cho đến khi mà việc xử lí DB hoàn thành rồi mới xóa. trường hợp mà đang xử lí như vậy thì sẽ phát sinh ra 1 event đó là blocked .

Điều cần chú ý ở đây là mặc dù event blocked có được phát sinh đi chăng nữa thì không hẳn việc xử lí sẽ thất bại. Sau khi event blocked phát sinh thì việc xử lí sẽ được tiến hành ngay sau khi phần xử lí xóa khả thi. và đương nhiên việc xử lí xóa này cũng sẽ phát sinh 2 event đó là success hoặc error.

Tiếp đến mình sẽ nói 1 chút cơ bản về IDBDatabase. IDBDatabase thì mang 2 properties đó là name và version. với phần name thì chúng ta sẽ không thể thay đổi được có nghĩa là khi mà tạo DB thì chúng ta chỉ được phép đặt tên 1 lần duy nhất và sẽ không thể đổi tên được nữa. trừ khi chúng ta xóa đi =)) . với version thì cũng như vậy không thể đổi được version trừ khi mà chúng ta nâng cấp version lên.

Thêm nữa thì IDBDatabase cũng có cả method close . nó là method để biểu thị việc hoàn thành 1 thao tác nào đó ở trên DB hay chưa. và không có giá trị trả về của method close.

Handle the object store

Như mình đã giới thiệu ở trên DB thì được lưu ở trên Object store . chính vì thế dẫu mà có DB đi chăng nữa thì nếu ở trong DB mà k có object store thì cũng không thế nào mà lưu các record vào đó được.

trong DB thì có thể tạo được nhiều Object store. Trong Object store thì chắc chắn có thể lưu được nhiều thông tin khác nhau chính vì vậy về cơ bản theo mình thì 1 Apprication thì chỉ cần 1 DB là ổn.

Đầu tiên thì mình sẽ giới thiệu về method createObjectstore của IDBDatabase, từ tên method chúng ta dễ dàng có thể thấy được là nó dùng để tạo ra object store đúng không 😃). về tham số truyền vào thì có 2 tham số, đầu tiên là tên của object store là string , tham số thứ 2 là option mình có thể lược bỏ .

Ở trong DB thì các object store được phân biệt với nhau bằng tên của các object store . chính vì thế khi mà tạo object store thì nhất định phải đặt tên cho object store có nghĩa là phần tên không thể lược bỏ được. Giá trị trả về của method object store là IDBObjectStore nó 1 object. IDBObjectStore chính là object store. Về IDBObjectStore thì mình sẽ giới thiệu sau. Tuy nhiên câu hỏi đặt ra ở đây là khi nào chúng ta dùng hàm createObjectstore thì tốt nhất ?, trong trường hợp khẩn cấp thì thì việc gọi createObjectstore thì là đương nhiên nhưng mà , việc tạo object store thì chúng ta nên gọi luôn ngay từ đầu thì là tốt nhất. chính vì thế trong trường hợp thông thường khi mà chúng ta muốn kiếm tra là trong DB có object store hay không thì mình sẽ gọi luôn createObjectStore để kiểm tra.

Tuy nhiên thì ở trong IndexedDB thì sẽ có 1 cách khác để thực hiện việc đó. đó chính là việc sử dụng versionchange transaction . thực tế createObjectStore thì chỉ có thể sử dụng mỗi method versionchange transaction. về transansaction là gì thì mình sẽ giới thiệu ở phần sau.

Ở phần trên khi mà giới thiệu về method open thì nếu mà trường hợp version của DB mà cũ hơn version của tham số truyền vào hoặc không có DB thì sẽ thực việc tạo mới và trong trường hợp đó thì versionchange transaction được kích hoạt.

Trường hợp khi mà versionchange transaction được kích hoạt thì giá trị trả về của method open trong IDBOpenDBRequest là upgradeneeded event được phát sinh. nếu event được phát sinh thì ở DB mới thì Thêm object store cho cơ sở dữ liệu mới bằng method createObjectStore, và xóa các object store cũ với deleteObjectStore là cần thiết.

ta có ví dụ sau

var request = indexedDB.open("test",1); // mở DB với name là test và version là 1.
//thực hiện xử lí việc update DB
request.addEventListener("upgradeneeded",function(e){
  //  ở trong đây là phần sử lí upgrade DB
});
//handle việc sử lí thành công hay không 
request.addEventListener("success",function(e){
  console.log(request.result);	// result được chứa ở IDBDatabase.
});

Thực ra thì upgradeneeded sẽ được phát sinh trước khi xảy ra event success hay error . Tuy nhiên thì ở thời điểm upgradeneeded properties result( chứa ở IDBDatabase) của IDBOpendRequest thì có khả năng sử dụng được. Do đó nên việc này nên được sử dụng với createObjectStore thì sẽ tốt hơn. để dễ hình dung mình có ví dụ bên dưới như sau:

var request = indexedDB.open("test",1);// mở DB với name là test và version là 1.
//thực hiện xử lí việc update DB
request.addEventListener("upgradeneeded",function(e){
  var db=request.result;	// result được chứa ở IDBDatabase.
  db.createObjectStore("foo");	tạo Object tên là foo,
});
//handle việc sử lí thành công hay không 
request.addEventListener("success",function(e){
  console.log(request.result);	// result được chứa ở IDBDatabase.
});

Thêm nữa event Object tại upgradeneeded là một loại của IDBVersionChangeEvent trong trường hợp này thì có 2 loại properties có thể sử dụng được đó là oldVersion và newVersion. Mỗi một cái thì sẽ log info trước khi update version DB và sau khi update version DB thì dựa theo log thì chúng ta có thể biết được sự thay đổi của nó trước và sau khi update version của DB. Dựa theo phần mình đã giải thích ở phía trên thì khi mà DB được tạo thành thì upgradeneeded cũng được phát sinh tuy nhiên trong trường hợp này thì oldVersion là sẽ là 0 . vì trước nó không có version nào được update. Giả sử việc DB dần dần trở lên phức tạp mà được nâng cấp phiên bản nhiều lần thì việc handle envent upgradeneeded được làm như sau .

var request = indexedDB.open("test",5);// mở DB với name là test và version là 5.
//thực hiện xử lí việc update DB
request.addEventListener("upgradeneeded",function(e){
  var db=request.result;	//result chứa trong IDBDatabase
  var old=e.oldVersion;	//version trước đó

  if(old<1){
    //xử lí DB khi được tạo lần đầu tiên
    db.createObjectStore("foo");	//tạo object store tên foo.
  }
  if(old<2){
    // khi version của DB được nâng từ 1 -> 2 thì thêm vào trong object store 
    db.createObjectStore("bar");	//tạo object store tên bar
  }
  if(old<3){
  //đồng dạng khi mà update từ 2-3
    db.createObjectStore("baz");
  }
  if(old<4){
    db.createObjectStore("qux");
  }
  if(old<5){
    db.createObjectStore("hoge");
  }
});
//handle event khi mà thành công 
request.addEventListener("success",function(e){
  console.log(request.result);	//result chứa trong IDBDatabase.
});

trong DB này có 5 object store là foo,bar,baz,qux,hoge nhưng mà . khi version bằng 1 thì chỉ có mỗi foo object store được. tạo khi lên version 2 thì có bar được thêm vào ... có nghĩa là mỗi lần lên version ta sẽ có từng cái object store được tạo ra.

Tổng Kết

Qua đây thì mình đã giới thiệu khá là chivề access to DB và handle xử object store giúp chúng ta nắm bắt được phần nào về IndexedDB. ở phần tiếp theo mình sẽ tiếp tục giới thiệu đến các bạn các phần tiếp theo của Indexed Database trong phần 3 khả năng phải 4 5 part mới hết được phần IndexedDB bài viết cũng khá lủng củng do văn phong mình cùi bắp mình sẽ chú ý và cải thiện hơn nữa . rất mong sự ủng hộ của các bạn (bow) Nguồn : https://uhyohyo.net/javascript/14_2.html


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí