Embedded Database

From Blognone

Jump to: navigation, search

ฐานข้อมูลฝังตัว

อโดบี AIR มีฐานข้อมูลฝังตัว SQLite ซึ่งสามารถถูกใช้โดยแอพพลิเคชันของ AIR SQLite เป็นฐานข้อมูลโอเพนซอร์สขนาดเล็กที่สนับสนุนทรานแสคชันแบบ ACID ไม่ต้องมีการตั้งค่าการทำงาน และมีคำสั่งของมาตรฐาน SQL92 เกือบทั้งหมด รวมถึงยังสนับสนุนชนิดข้อมูลแบบข้อความ และ BLOB ที่มีขนาดถึงสองกิกะไบท์ ข้อมูลที่เกี่ยวกับฐานข้อมูลทั้งหมดจะเก็บไว้ในไฟล์เดียว และสามารถย้ายไปยังคอมพิวเตอร์เครื่องอื่นได้อย่างอิสระ ถึงแม้ว่าจะใช้ลำดับการเรียงไบท์ไม่เหมือนกัน

Tip: คุณสามารถหาข้อมูลเพิ่มเติมเกี่ยว SQLite ได้ที่หน้าเว็บไซท์ของโครงการที่ http://www.sqlite.org

ในขณะนี้ เมื่อทำงานกับฐานข้อมูลในเครื่องคอมพิวเตอร์เดียวกันจาก AIR ทรานแสคชันทั้งหมดจะเป็นแบบอซิงโครนัส รูปแบบการตั้งค่าแบบนี้ทำให้ส่วนติดต่อผู้ใช้สามารถทำงานต่อไปได้โดยที่ฐานข้อมูลทำการประมวลผลอยู่เบื้องหลัง ในการติดตามการทำงานของฐานข้อมูล แต่ละแอพพลิเคชันจะต้องสร้างและจดทะเบียนอีเวนท์ที่ตัวเองสนใจ


Contents

การเชื่อมต่อกับฐานข้อมูล

ปัญหา

คุณต้องการที่จะเข้าถึงฐานข้อมูลท้องถิ่นในการที่จะทำงานกับแผนผังข้อมูลหรือว่าแก้ไขข้อมูล

วิธีแก้

การสร้างและเชื่อมต่อฐานข้อมูลสามารถทำได้ใช้เมธอด SQLConnection.open()

อธิบาย

SQLite เก็บข้อมูลทั้งหมดไว้ในไฟล์เดียวบนดิสค์ นี่หมายถึงว่าก่อนที่แอพพลิเคชันจะสามารถเข้าถึงฐานข้อมูล มันจะต้องทำการอ้างถึงไฟล์ฐานข้อมูลก่อน แอพพลิเคชันหนึ่ง ๆ สามารถเข้าถึงไฟล์ฐานข้อมูลกี่ไฟล์ก็ได้ โดยฐานข้อมูลจะถูกจัดการผ่านชนิดข้อมูล SQLConnection ใน API ของ AIR

ไฟล์ฐานข้อมูลสามารถอ้างอิงถึงผ่านทางเมธอด File.resolve() ซึ่งรับอาร์กิวเมนท์ตัวเดียวคือชื่อของไฟล์ที่จะถูกอ้างถึง ไฟล์ที่ยังไม่มีอยู่ก็สามารถถูกอ้างอิงถึงได้เช่นกัน โดยคุณสมบัติ File.exists ของไฟล์นั้นจะให้ค่าทางตรรกะที่บอกว่าไฟล์นั้นมีอยู่หรือไม่:

var db = new air.SQLConnection(); 
var file = air.File.applicationStorageDirectory.resolve( "mycrm.db" );

นามสกุลของไฟล์ฐานข้อมูลนั้นไม่เฉพาะเจาะจงและสามารถตั้งชื่อตามความจำเป็นสำหรับแอพพลิเคชัน

ทรานแสคชันของฐานข้อมูลเกิดขึ้นแบบอซิงโครนัส นั่นหมายถึงว่าแอพพลิเคชันจะต้องทำการสร้างและลงทะเบียน handler สำหรับอีเวนท์ที่ตัวเองสนใจก่อน ในกรณีของการสร้างการเชื่อมต่อไปยังฐานข้อมูล อีเวนท์ SQLEvent.OPEN จะสามารถถูกติดตามได้ ในจำนวนคุณสมบัติหลาย ๆ อย่าง คุณสมบัติ SQLEvent.type สามารถถูกใช้เพื่อตรวจสอบสถานะของฐานข้อมูล

db.addEventListener( air.SQLEvent.OPEN, doDbOpen ); 

function doDbOpen( event ) 
{ 
   alert( "Connected" ); 
} 

การเรียกใช้เมธอด SQLConnection.open() สามารถรับอาร์กิวเมนท์ได้หลายแบบ อาร์กิวเมนท์พื้นฐานก็คือตัวอ้างอิงไฟล์ฐานข้อมูล และค่าทางตรรกะที่บ่งบอกว่าฐานข้อมูลนี้ควรจะถูกสร้างใหม่ในกรณีที่มันยังไม่มีอยู่หรือไม่ การทำแบบนี้จะเป็นการสร้างฐานข้อมูลขึ้นมาใหม่ถ้ามันยังไม่มีอยู่ และสร้างการเชื่อมต่อไปยังฐานข้อมูลนั้นในขณะเดียวกัน

db.open( file, true);

ในขณะที่ฐานข้อมูลจะปิดตัวเองโดยอัตโนมัติเมื่อแอพพลิเคชันหยุดทำงาน นักพัฒนาควรจะเรียกใช้ SQLConnection.close() ในขณะที่อีเวนท์ onunload เกิดขึ้น เมธอด SQLConnection.close() ไม่รับอาร์กิวเมนท์ใด ๆ การใช้เวลาเพื่อปิดการทำงานฐานข้อมูลเองช่วยรัปบะกันว่าข้อมูลจะไม่เสียหายจากอุบัติเหตุใด ๆ และเป็นการปฏิบัติที่ดีที่ควรกระทำทุกครั้ง

<html> 
<head> 

<title>Connecting to a Database</title> 
<script type="text/javascript" src="AIRAliases.js"> </script> 

<script> 
var db =new air.SQLConnection(); 

function doDbOpen( event )
{ 
   alert( "You are now connected to the database." ); 
} 

function doLoad() 
{ 
   var file = air.File.applicationResourceDirectory.resolve( "crm.db" ); 
   db.addEventListener( air.SQLEvent.OPEN, doDbOpen ); 
   db.open( file, true ); 
} 

function doUnload() 
{ 
   db.close(); 
} 

</script> 
</head> 
<body onload="doLoad();" onunload="doUnload()"> 

</body> 
</html>

การสร้างตารางในฐานข้อมูล

ปัญหา

แอพพลิเคชันมีรูปแบบของสคีมาที่ต้องการใช้งานจากระบบเก็บข้อมูล

วิธีแก้

สคีมาของฐานข้อมูลสามารถถูกสร้างโดยใช้คลาส SQLStatement และคำสั่งตามมาตรฐาน SQL92

อธิบาย

เมื่อไฟล์ของฐานข้อมูลหนึ่งถูกสร้างขึ้นและการเชื่อมต่อไปยังฐานข้อมูลนั้นถูกสร้างเรียบร้อยแล้ว ขั้นตอนต่อไปก็น่าจะเป็นการสร้างสคีมาที่ต้องการ ขั้นตอนนี้สามารถทำได้โดยใช้คำสั่งตามมาตรฐาน SQL92 ร่วมกับคลาส SQLStatement และคลาส SQLStatement จะดำเนินการตามคำสั่งดังกล่าวกับฐานข้อมูลที่ระบุไว้

เนื่องจากว่าทรานแซคชันของฐานข้อมูลจะเกิดขึ้นแบบอซิงโครนัส ที่ ๆ ดีที่สุดที่จะทำการตรวจสอบสคีมาที่ต้องการว่ามีอยู่แล้วหรือไม่หรือว่าจำเป็นต้องสร้างใหม่หรือไม่ ก็คือใน handler ของอีเวนท์ SQLEvent.OPEN ณ จุดนี้ แอพพลิเคชันสามารถมั่นใจได้ว่ามีการเชื่อมต่อสำหรับการปฏิบัติตามคำสั่งเรียบร้อยแล้ว ในขณะเดียวกัน handler สำหรับอีเวนท์จะต้องถูกลงทะเบียนกับอินสแตนซ์ของ SQLStatement:

var stmt = new air.SQLStatement(); 
stmt.addEventListener( air.SQLErrorEvent.ERROR, doStmtError ); 
stmt.addEventListener( air.SQLEvent.RESULT, doStmtResult ); 

เมื่อใช้กับออบเจ็คท์ SQLStatement อีเวนท์ SQLErrorEvent.ERROR จะถูกเรียกเมื่อเกิดความผิดพลาดขึ้นในขณะที่เรียกใช้เมธอด SQLStatement.next() หรือว่า SQLStatement.execute() ในทางกลับกัน อีเวนท์ SQLEvent.RESULT จะถูกเรียกเมื่อผลลัพธ์ของคำสั่งถูกส่งกลับมาจากฐานข้อมูล นี่มักจะบ่งบอกว่าคำสั่งถูกปฏิบัติสำเร็จแล้ว

function doStmtError( event ) 
{ 
   alert( "There has been a problem executing the statement" ); 
}

function doStmtResult( event ) 
{ 
   alert( "The database table has been created." ); 
} 

อินสแตนซ์ของ SQLConnection ที่จะถูกใช้ในการดำเนินการตามคำสั่งจะต้องเชื่อมต่อเรียบร้อยแล้วในการที่จะทำงานตามคำสั่ง SQL ใด ๆ อินสแตนซ์ของ SQLConnection สามารถถูกมอบหมายให้กับคุณสมบัติ SQLStatement.sqlConnection คุณสมบัติ SQLStatement.text สามารถถูกมอบหมายด้วยคำสั่ง SQL ที่ต้องการดำเนินการ ท้ายที่สุด เมธอด SQLStatement.execute() ก็จะถูกเรียกใช้

stmt.sqlConnection = db; 
stmt.text = "CREATE TABLE IF NOT EXISTS contact ( " + 
   "id INTEGER PRIMARY KEY AUTOINCREMENT, " + 
   "first TEXT, " +
   "last TEXT )"; 
stmt.execute(); 

ในกรณีนี้ คำสั่ง CREATE TABLE ถูกส่งไปยังฐานข้อมูล คำสั่งชนิดอื่น ๆ ของ SQL เช่น SELECT INSERT UPDATE และ DELETE สามารถถูกดำเนินการในลักษณะเดียวกัน เมธอด SQLStatement.execute() สามารถรับอาร์กิวเมนท์เพิ่มเติมได้สองตัว คือจำนวนของแถวข้อมูลที่ต้องการพรีเฟทช์และเรสปอนเดอร์ออปเจ็คท์ที่ใช้จัดการกับอีเวนท์ต่าง ๆ

ค่ามาตรฐานของฟรีเฟทซ์คือ -1 ซึ่งมายถึงว่าแถวข้อมูลทั้งหมดควรจะถูกส่งกลับมา เรสปอนเดอร์ออบเจ็คท์คือออบเจ็คท์ที่ถูกออกแบบมาเฉพาะสำหรับจัดการกับสถานหรือว่าอีเวนท์ใด ๆ ที่อาจจะเกิดขึ้นระหว่างการดำเนินงาน ค่ามาตรฐานของเรสปอนเดอร์ออบเจ็คท์คือว่างเปล่า ซึ่งในกรณีนี้ การจัดการกับอีเวนท์จะถูกลงทะเบียนกับออบเจ็คท์ SQLStatement โดยตรง

<html> 
<head> 
<title>Creating Database Tables</title> 
<script type="text/javascript" src="AIRAliases.js"> 
</script> 
<script> 
var db = null; 
var stmt = null 

function doDbOpen( event ) 
{ 
   stmt =new air.SQLStatement(); 
   stmt.addEventListener( air.SQLErrorEvent.ERROR, doStmtError ); 
   stmt.addEventListener( air.SQLEvent.RESULT, doStmtResult ); 
   stmt.sqlConnection = db; 
   stmt.text = "CREATE TABLE IF NOT EXISTS contact ( " + 
               "idINTEGERPRIMARYKEYAUTOINCREMENT,"+ 
               "first TEXT, " + 
               "last TEXT )"; 
   stmt.execute(); 
}

function doLoad() 
{ 
   var file = 
   air.File.applicationResourceDirectory.resolve( "crm.db" ); 
   db =new air.SQLConnection(); 
   db.addEventListener( air.SQLEvent.OPEN, doDbOpen ); 
   db.open( file, true ); 
} 

function doStmtResult( event ) 
{ 
   alert( "The database table has been created." ); 
} 

function doStmtError( event ) 
{ 
   alert( "There has been a problem executing a 
   statement:\n" + event.error.message ); 
} 

function doUnload() 
{ 
   db.close(); 
} 

</script> 
</head> 
<body onload="doLoad()" onunload="doUnload()"> 
</body> 
</html>

การเก็บข้อมูลในฐานข้อมูล

ปัญหา

แอพพลิเคชันหนึ่งต้องการเก็บข้อมูลจากผู้ใช้ลงในฐานข้อมูลในดิสค์

วิธีแก้

คำสั่ง INSERT ตามมาตรฐาน SQL92 สามารถถูกเรียกใช้ในการสร้างใช้งานผ่านทางคลาส SQLStatement

อธิบาย คำสั่งตามมาตรฐาน SQL92 สามารถถูกเรียกใช้ผ่านอ๊อบเจ็คท์ SQLStatement เมื่อใช้พร้อมกับไฟล์ฐานข้อมูลและสคีมาที่ถูกต้อง อ๊อบเจ็คท์ของ SQLStatementหนึ่ง ๆ สามารถถูกใช้ซ้ำกันสำหรับเรียกใช้คำสั่งหลาย ๆ คำสั่งได้ เมื่อใช้งานอ๊อบเจ็คท์ SQLStatement หนึ่ง ๆ หลายครั้ง สิ่งสำคัญคือต้องแยกแยะชนิดของคำสั่งที่จะถูกเรียกใช้ มีหลายวิธีที่สามารถแยกแยะคำสั่งเหล่านั้น

function doSave() 
{ 
   var first = document.getElementById( "txtFirst" ).value; 
   var last = document.getElementById( "txtLast" ).value; 
   stmt.text = "INSERT INTO contact VALUES ( " + 
       "NULL, " + 
       "'" + first + "', " + 
       "'" + last + "' )"; 
   stmt.execute(); 
}

การเข้าถึงข้อมูลในฐานข้อมูล