Cordova SQLite 事务数据不持久

Posted

技术标签:

【中文标题】Cordova SQLite 事务数据不持久【英文标题】:Cordova SQLite transaction data not persistent 【发布时间】:2021-04-04 20:06:08 【问题描述】:

我要转储,使用cordova-sqlite-plugin 将持久性数据存储在sqlite 数据库中。每次我重新加载浏览器时,开始:“cordova emulate browser”,写入的数据就消失了。当我启动 android 模拟器时也是如此:“cordova emulate android”。在 android 模拟器中,我必须重新启动并重新打开应用程序,以消除问题。 我尝试了各种方法来解决这个问题:

    添加各种 database.close() 部分。请参阅 javascript 代码中未注释的部分。每次执行此操作时,我都会在浏览器 javascript 控制台中收到以下消息:“数据库在打开操作期间关闭”和“无法启动下一个事务:数据库未打开” 我检查了数据中继是否写入,请参阅插入或更新下方的 console.log 部分。 在database.open部分添加了“androidDatabaseProvider” 等。等

这里是javascript代码:

var database = null;

document.addEventListener("deviceready", function()
  database = window.sqlitePlugin.openDatabase(name: 'fts-running.sqlite', location: 'default', androidDatabaseProvider: 'system', androidLockWorkaround: 1);
  initDatabase();
  showIntruduction();
  // database.close();
);

function successcb()
  console.log('INFO: Database opened succesfully!')


function errorcb()
  console.log('ERROR: Database open failed!')


function initDatabase() 
  console.log('INFO: initDatabase started!');

  database.transaction(function(tx) 
    tx.executeSql('CREATE TABLE IF NOT EXISTS running_current_run (run_id bigint PRIMARYKEY, run_start_datetime datetime, run_end_datetime datetime)');
    tx.executeSql('CREATE TABLE IF NOT EXISTS running_history (run_id bigint PRIMARYKEY, run_total_distance float, run_average_pace bigint, run_average_speed float, run_start_datetime datetime, run_end_datetime datetime)');
    tx.executeSql('CREATE TABLE IF NOT EXISTS running_geodata (run_id bigint PRIMARYKEY, run_coordinate_latitude float, run_coordinate_longitude float, run_current_datetime datetime)');
    tx.executeSql('CREATE TABLE IF NOT EXISTS running_settings (intruduction_viewed boolean)');
    tx.executeSql('SELECT * FROM running_settings', [], function(tx, rs) 
      if(rs.rows.length == 0) 
        tx.executeSql('INSERT INTO running_settings (intruduction_viewed) VALUES (false)', [], function(tx, rs) 
          console.log('rs.insertId: ' + rs.insertId);
          console.log('rs.rowsAffected: ' + rs.rowsAffected);
        , function(tx, error) 
          console.log('INSERT error: ' + error.message);
        );
      
    );
  , function(error) 
    console.log('transaction error: ' + error.message);
  , function() 
    console.log('transaction ok');
  );


function showIntruduction() 
  console.log('INFO: showIntruduction started!');

  database.transaction(function(tx) 
    tx.executeSql('SELECT intruduction_viewed FROM running_settings', [], function(tx, rs) 
      if(rs.rows.item(0).intruduction_viewed == false || rs.rows.item(0).intruduction_viewed == null) 
        var element = document.getElementById('intruduction_wrapper');
        element.style.display = "block";
      
    );
  , function(error) 
    console.log('ERROR: ' + error.message);
  , function() 
    console.log('INFO: showIntruduction finished!');
  );


function set_intruduction_viewed() 
  console.log('INFO: set_intruduction_viewed started!');
  // database = window.sqlitePlugin.openDatabase(name: 'fts-running.db', location: 'default');

  database.transaction(function(tx) 
    tx.executeSql('UPDATE running_settings SET intruduction_viewed = true WHERE intruduction_viewed = false', [], function(tx, rs) 
      var element = document.getElementById('intruduction_wrapper');
      element.style.display = "none";
      console.log('rs.insertId: ' + rs.insertId);
      console.log('rs.rowsAffected: ' + rs.rowsAffected);
    , function(tx, error) 
      console.log('Update error: ' + error.message);
    );
  , function(error) 
    console.log('ERROR: ' + error.message);
  , function() 
    console.log('INFO: set_intruduction_viewed finished!');
  );
  // database.close();

这是我的html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" href="css/globalstyle.css"></link>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script src="cordova.js"></script>
        <script src="plugins/cordova-sqlite-storage/www/SQLitePlugin.js"></script>
        <script src="js/functions.js"></script>
    </head>

    <body>
      <div id="intruduction_wrapper">
        <div id="intruduction_text">Hallo</div>
        <button id="confirmation" onclick="set_intruduction_viewed()" type="button">Confirm</button>
      </div>

      <div class="snap-wrapper">
        <div class="snap-items section-one">
          <div id="run_propperties">
              <div id="top_section"></div>
              <div id="mid_section_left"></div>
              <div id="mid_section_right"></div>
          </div>
          <div class="bottom">
            <button class="button" id="start_run" type="button" onclick="">Start action</button>
            <div class="dots">
              <span class="dot" id="dot1"></span>
              <span class="dot" id="dot2"></span>
            </div>
          </div>
        </div>
        <div class="snap-items section-two">
          <div class="bottom">
            <div class="dots">
              <span class="dot" id="dot3"></span>
              <span class="dot" id="dot4"></span>
            </div>
          </div>
        </div>
      </div>

    </body>

</html>

这是我的css:

body,html,.snap-wrapper,.snap-items 
  margin: 0;
  padding: 0;


body 
  overflow-y: hidden;


#intruduction_wrapper 
  display: none;
  position: fixed;
  z-index: 1;
  left: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
  overflow: auto;
  background-color: rgb(0,0,0);
  background-color: rgba(0,0,0,0.4);
  display: flex;
  flex-direction: column;
  align-items: center;


#intruduction_text  
  height: 95vh;
  width: 95vw;
  color: white;
  font-size: 1.5rem;


#confirmation 
  


.snap-wrapper 
  scroll-snap-type: x mandatory;
  display: flex;
  -webkit-overflow-scrolling: touch;
  overflow-x: scroll;


.snap-items 
  border-right: 1px solid white;
  min-width: 100vw;
  height: 100vh;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;


#run_propperties 
  width: 100vw;
  height: 30vh;
  background-color: grey;
  display: flex;
  flex-direction: column;


#top_section 
  background-color: black;
  width: 100vw;
  height: 10vh;


.bottom 
  margin-top: auto;
  display: flex;
  flex-direction: column;
  align-items: center;


.button 
  width: 50vw;
  height: 5vh;
  margin-bottom: 1vh;
  border: 0;
  color: white;
  background-color: grey;


.button:hover 
  color: black;
  background-color: grey;


.dot 
 margin-left: 0.5vw;
 height: 12px;
 width: 12px;
 border-radius: 50%;
 display: inline-block;
 margin-bottom: 1vh;


.section-one span:nth-of-type(1)  
  background-color: black;


.section-one span:nth-of-type(2) 
  background-color: #bbb;


.section-two span:nth-of-type(1)  
  background-color: #bbb;


.section-two span:nth-of-type(2) 
  background-color: black;

我搜索了很多,自己解决这个问题,这是我最后的希望,解决它。我非常感谢您的所有信息和帮助!

问候 乔纳斯

【问题讨论】:

我不是 JavaScript 专家,但我用过 SQLite。我希望您需要在更新和插入语句之后添加一个 tx.comit() 调用。 您在“initDatabase()”之后立即调用“showIntroduction()”。当第二个被调用时,第一个调用的 Sql 事务肯定不会完成。我认为您需要等到回调函数 (function(tx, rs)) 完成后再执行更多 Sql tarnsactions - 即将任何后续 sql 操作移动到第一个回调中。 感谢您的 cmets!我现在在 initDatabase 函数的成功中移动了 showInstruction 部分。我从这两个函数中都收到了成功消息,但没有存储数据。 【参考方案1】:

我忘了在数据库打开部分的回调和错误函数。添加功能后,一切都对我有用。 这里是功能性的 openDatabase 部分:

document.addEventListener("deviceready", function()
  database = window.sqlitePlugin.openDatabase(name: 'fts-running.db', location: 'default', androidDatabaseProvider: 'system', androidLockWorkaround: 1, function(db) 
    console.log('Database opend succesfully!');
    initDatabase();
    // showIntruduction();
  , function(error) 
    console.log('Open database ERROR: ' + JSON.stringify(error));
  );
);

【讨论】:

以上是关于Cordova SQLite 事务数据不持久的主要内容,如果未能解决你的问题,请参考以下文章

将 Cordova-Sqlite 2 插件集成到现有的 IBM MobileFirst 应用程序中

Android学习之基础知识九 — 数据存储(持久化技术)之SQLite数据库存储

cordova-sqlite-ext 可以读取 sd 卡(Android)上的数据库吗?

SQLite 数据库存储

升级到 64 位时 Cordova Sqlite 数据库错误

在 Windows 10 中使用 cordova-plugin-file 复制 SQLite 数据库 cordova-sqlite-storage