[英]How do I detect if sqlite3 created a database file?
我正在編寫一個程序,它使用sqlite3數據庫文件來存儲其數據。 如果我打開一個數據庫文件
sqlite3_open_v2(filename, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)
如果數據庫文件不存在,則創建該數據庫文件。 如何在打開數據庫文件之前查明數據庫文件是否存在? sqlite3 shell使用如下代碼:
/* Go ahead and open the database file if it already exists. If the
** file does not exist, delay opening it. This prevents empty database
** files from being created if a user mistypes the database name argument
** to the sqlite command-line tool.
*/
if( access(data.zDbFilename, 0)==0 ){
open_db(&data, 0);
}
但是,當access
調用之后和open_db
調用之前(檢查時間與使用時間)之間的另一個進程創建數據庫文件時,此代碼具有競爭條件。
另一個答案(我現在找不到)建議檢查application_id
和user_version
字段。 如果它們為零,則只創建一個數據庫。 我研究了這種方法,發現許多應用程序實際上並不打算在新創建的數據庫中設置這些字段,所以這種方法充其量是模糊的,我不認為它解決了我的問題。
有沒有一種方法可以確定數據庫在打開之前是否存在,而不涉及這樣的競爭條件? 如果我只能通過sqlite3查明數據庫文件是否已初始化(如在sqlite3標題中填充了截斷文件),也是可以接受的。
擁有這樣一個例程的目的是為了能夠找出是否需要在數據庫中創建我需要的所有表。 我不想意外地覆蓋另一個應用程序放置在那里的另一個文件。
可以在以下bash腳本中找到該問題的簡化說明。 它模擬兩個應用程序。 它們都以類似的方式工作:
test.db
test
並在其中寫入一行。 第一個應用程序的值為1,第二個應用程序的值為2。 這是代碼:
#!/bin/sh
# sleeps are inserted to make the race conditions easier to trigger
application() {
echo Checking if database exists...
[ ! -f test.db ]
status=$?
sleep 2
if (exit $status)
then
echo Database not found, making tables
sqlite3 test.db "CREATE TABLE IF NOT EXISTS test (a);"
sleep 2
echo Writing initial record into database
sqlite3 test.db "INSERT INTO test VALUES ($1);"
sleep 2
else
echo Database found, checking if it belongs to me
fi
echo Printing content of database
sqlite3 test.db "SELECT * FROM test;"
}
rm -f test.db
echo First test: app1 and app1 race
application 1 & (sleep 1 ; application 1)
rm -f test.db
echo Second test: app2 and app1 race
application 2 & (sleep 1 ; application 1)
我的目標是確保以下情況永遠不會發生:
如果application
編程正確,則每次運行只會初始化數據庫(如果之前未初始化)。 因此,您將看到的唯一輸出是僅包含第1
行的數據庫或僅包含第2
行的數據庫。
無法將新創建的數據庫與先前創建的空數據庫區分開來。
但是,空數據庫是唯一存在此問題的數據庫。 可以通過檢查sqlite_master
表是否為空來檢測任何其他數據庫。 在事務中執行此操作並創建表,並且沒有競爭條件。
如果您第一次寫入數據庫(實際創建文件時)是設置application_id ,那么您知道任何具有其他ID的文件都不是您的。 (已注冊的申請ID是唯一的。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.