اندازهی قلم متن
تخمین مدت زمان مطالعهی مطلب:
هشت دقیقه
در مقاله قبلی با یکی از کتابخانههای مدیریت دیتابیس sqlite آشنا شدیم و و یاد گرفتیم که چگونه یک دیتابیس جدید را بسازیم و اطلاعات را از آن دریافت کنیم. در این مقاله قصد داریم، بیشتر در مورد دستورات این کتابخانه بدانیم و بفهمیم که چگونه باید آنها را به کار بست.
دستورات بدون خروجی:
یک سری از دستورات هستند که خروجی ندارند و رکوردی را باز نمیگردانند و برای اجرای دستوراتی چون افزودن، به روزرسانی و حذف بسیار مناسبند. اجرای این دستورات را ما به متدی به نام run میسپاریم. در دفعه قبل که از این دستور استفاده کردیم، پارامتری برای تعیین کردن نداشت؛ ولی در این مقاله، دستور با پارامتر آن را اجرا میکنیم:
ابتدا کدهای زیر را به فایل html، برای درج رکورد جدید اضافه میکنیم:
دستورات بدون خروجی:
یک سری از دستورات هستند که خروجی ندارند و رکوردی را باز نمیگردانند و برای اجرای دستوراتی چون افزودن، به روزرسانی و حذف بسیار مناسبند. اجرای این دستورات را ما به متدی به نام run میسپاریم. در دفعه قبل که از این دستور استفاده کردیم، پارامتری برای تعیین کردن نداشت؛ ولی در این مقاله، دستور با پارامتر آن را اجرا میکنیم:
ابتدا کدهای زیر را به فایل html، برای درج رکورد جدید اضافه میکنیم:
First Name:<br/> <input type="text" id="txtfname" /><br/> Last Name:<br/> <input type="text" id=txtlname /><br/> Number:<br/> <input type="tel" id="txttel" /><br/> <button id="btnsubmit">Save</button><br/>
function GetValues() { let fname=$("#txtfname").val(); let lname=$("#txtlname").val() let tel=$("#txttel").val(); let row= { fname:fname, lname:lname, number:tel }; return row; }
$("#btnsubmit").click((e)=>{ e.preventDefault(); let row=GetValues(); //save in db //get last id let statement==db.prepare("select id from numbers order by id desc limit 1"); let lastRecord=statement.getAsObject({}).id; row.id=lastRecord++; let count=db.prepare("select count(*) as count from numbers order by id desc").getAsObject({}).count; statement.free(); let insertCommand="insert into numbers values(?,?,?,?)"; db.run(insertCommand,[row.id,row.fname,row.lname,String(row.number)]) let newcount=db.prepare("select count(*) as count from numbers order by id desc").getAsObject({}).count; SaveChanges(); //show in the table if(count<newcount) { AddToTable(row); } }); });
var statement= db.prepare("SELECT * FROM NUMBERS WHERE fname=@fname AND lname=@lname"); var result = statement .getAsObject({'@fname' :'ali', '@lname' : 'yeganeh'});
statement.bind(['hossein','yeganeh']);
متد step همانند متدهای next در cursor یا read در datareader عمل میکند و با هر بار صدا زدن، یک رکورد، به سمت جلو حرکت میکند. دریافت هر رکورد جاری توسط متد get و نوع خروجی آرایه انجام میشود:
while(statement.step()) { var rec=statement.get(); }
بعد از اینکه کارمان با آن تمام شد، برای پاکسازی حافظه از متد free استفاده میکنیم. در دستورات بعد، شیء statement را مستقیما مورد استفاده قرار دادهایم و توسط آن تعداد رکوردها را دریافت کردهایم. سپس با استفاده از متد run دستور درج را دادهایم. اینبار این متد را به شکل متفاوتی استفاده کردیم و به آن پارامتری هم دادیم. نحوه ارائه پارامتر به این متد، باید به صورت آرایه و به ترتیب علامتهای ؟ باشد. نهایتا با دریافت تعداد رکوردهای جاری و مقایسه با تعداد رکوردهای سابق متوجه میشویم که آیا رکوردی اضافه شده است یا خیر؟ در صورتی که اضافه شده است، باید رکورد جدید در جدول، توسط جی کوئری نمایش داده شود و تغییرات دیتابیس هم روی دیسک سخت ذخیره شوند. چون دیتابیس مورد استفاده به صورت in-memory یعنی مقیم در حافظه مورد استفاده قرار میگیرد، باید کل دیتابیس، بر روی دیسک سخت رونویسی شود. متد SaveChanges شامل کد زیر است که حاوی کد ارسال پیام به Main Thread یا Main Process میباشد تا در دیسک سخت بنویسد:
const {ipcRenderer} = require('electron'); function SaveChanges() { ipcRenderer.send("SaveToDb"); }
const {ipcMain} = require('electron'); ipcMain.on("SaveToDb", (event, arg) => { SaveToDb(); }); function SaveToDb() { var data=db.export(); var buffer=new Buffer(data); fs.writeFileSync(dbPath,buffer); }
ویرایش رکورد
ابتدا template string سطر جدول را به شکل زیر تغییر میدهیم:
function AddToTable(row) { let tableBody=$("#people"); let rowTemplate=`<tr><td>${row.fname}</td><td>${row.lname}</td><td>${row.number}</td><td><button class= "btn btn-success btnupdate" data-id="${row.id}" >Edit</button></td></tr>`; tableBody.append(rowTemplate); }
سپس در تگ اسکریپت، در رویداد ready جی کوئری، این دستورات را اضافه میکنیم:
$("#people").on('click','.btnupdate',function(e) { e.preventDefault(); row.id=$(this).data("id"); let row=GetValues(); db.run("UPDATE NUMBERS SET FNAME=?,LNAME=?,NUMBER=? WHERE ID=?",[row.fname,row.lname,row.number,row.id]); SaveChanges(); tr=$(this).closest("tr"); let column=0; tr.find("td").each(function(index) { oldRow=$(this); switch(column) { case 0: //fname oldRow.text(row.fname); break; case 1: //lname oldRow.text(row.lname); break; case 2: //number oldRow.text(row.number); break; } column++; }); });
ابتدای id ذخیره شده در المان و مقادیر جدید را دریافت میکنیم. با استفاده از متد run کوئری به روزرسانی را به همراه پارامترها ارسال میکنیم و نتیجه را بر روی دیسک سخت ذخیره میکنیم. از اینجا به بعد نقش جی کوئری پر رنگتر میشود و به خوبی میتوانیم اهمیت آن را درک کنیم. سطر دکمه جاری را پیدا میکنیم و مقادیر جدید را ستون به ستون تغییر میدهیم.
خواندن و بازگردانی رکوردها
در مقاله قبلی با دستور each آشنا شدیم که یک متد غیرهمزمان بود و نتیجه هر رکورد را با یک callback به ما بازگشت میداد. در اصل این متد شامل 4 پارامتر است: پارامتر اول آن، کوئری ارسالی است. پارامتر دوم آن، پارامتر کوئریها ، پارامتر سوم، تابع callback که به ازای هر رکورد اجرا میشود و پارامتر چهارم، تابع done می باشد. یعنی زمانی که کلیه رکوردها بازگشت داده شدند. شکل کامل آن به این صورت است:
db.each("SELECT name,age FROM users WHERE age >= $majority", {$majority:18}, function(row){console.log(row.name)}, function(){console.log("done");} );
در این مقاله با متد دیگری به نام exec نیز آشنا میشویم که بازگردانی مقادیر در آن به صورت همزمان صورت میگیرد و توانایی آن را دارد که چندین دستور select را بازگردانی کند. به عنوان مثال دستور زیر را در نظر بگیرید:
SELECT ID FROM NUMBERS;SELECT FNAME,LNAME FROM NUMBERS
[ {columns: ['id'], values:[[1],[2],[3]]}, {columns: ['fname','lname'], values:[['ali','yeganeh'],['hossein','yeganeh'],['mohammad','yeganeh']]} ]
var records=db.exec("select * from numbers"); let values=records[0].values; let length=values.length; for(let i=0;i<length;i++) { let object=values[i]; let row={ id:object[0], fname:object[1], lname:object[2], number:object[3] }; AddToTable(row); }