Ionic + sqlite: Cannot access sqlite tables on ios (cordova SQLite)


#1

I am using Ionic for creating my hybrid app.

I am using sqlite as database. On Android i can access all my stored data without any problems but on iOS it fails. I retrieve the following error in the xcode debugging console (I am using an iPhone 6s Plus for testing):

[debug] OPEN database: rcsappmobile.db
[debug] Initializing SQLitePlugin
[debug] Detected docs path: /var/mobile/Containers/Data/Application/<UUID>/Documents
[debug] Detected Library path: /var/mobile/Containers/Data/Application/<UUID>/Library
[debug] no cloud sync at path: /var/mobile/Containers/Data/Application/<UUID>/Library/LocalDatabase
[debug] open full db path: /var/mobile/Containers/Data/Application/<UUID>/Library/LocalDatabase/rcsappmobile.db
[debug] Good news: SQLite is thread safe!
[debug] DB opened: rcsappmobile.db

[debug] SELECT av.id, av.name FROM app_venues av WHERE av.active ORDER BY av.venuename ASC
[debug] result: 
[debug] {"$$state":{"status":0}}
[debug] MultipleResultHandler
[debug] Default Error Handler -> Error processing SQL:  undefined: undefined
[debug] Default Error Handler -> Error processing SQL:  5: a statement error callback did not return false: no such table: app_venues

In xcode I have also this warning:

warning: no rule to process file '/Library/WebServer/Documents/rcs/dev/platforms/ios/Myapp/Plugins/me.rahul.plugins.sqlDB/sqlDB.h' of type sourcecode.c.h for architecture arm64

So far my problem.

That’s my code:

controllers.js:

var dashboardCtrl = function ($scope, $ionicPlatform, $cordovaDevice, DbAccess) {
  console.log('dashboardCtrl');
  $ionicPlatform.ready(function () {
    console.log('dashboard -> platform ready');
      DbAccess.openDb();
  });
};
dashboardCtrl.$inject = ['$scope', '$ionicPlatform', '$cordovaDevice', 'DbAccess'];


var venuesCtrl = function ($scope, $ionicPlatform, $cordovaDevice, VenuesQueries) {
  console.log('venuesCtrl');
  $ionicPlatform.ready(function () {
    console.log('venue -> platform ready');
      VenuesQueries.getVenues().then(function(result) {
        $scope.outputs = result;
        var len = Object.keys(result).length;
        if(len > 0) {
          $scope.outputs = result;
        } else {
          console.log('No records found in database.');
        }
      }, function(error) {
        console.error(error);
      });
  });
};
venuesCtrl.$inject = ['$scope', '$ionicPlatform', '$cordovaDevice', 'VenuesQueries'];

service.js

var DbAccess = function ($q, $cordovaSQLite, $ionicPlatform, $cordovaDevice, $log) {
  var DbAccess = {};
  var db = {};
  var dbName = 'rcsappmobile.db';
  $ionicPlatform.ready(function () {
    console.log('Service: DbAccess -> platform ready');
    
      var platform = $cordovaDevice.getPlatform();
      // dbLocation = 0, will copy the db to default SQLite Database Directory
      // dbLocation = 1, will copy the database to /Library folder
      // dbLocation = 2, will copy the database to /Library/LocalDatabase folder (Disable iCloud Backup)
      var dbLocation = 1;
      if (platform === 'Android') {
        dbLocation = 0;
      }

      if (window.sqlitePlugin) {

        DbAccess.openDb = function() {
          console.log('Open database '+dbName);
          // open database
          function dbopen() {
            db = window.sqlitePlugin.openDatabase({
              name: dbName,
              iosDatabaseLocation: 'default',
              createFromLocation: 1
            });
          }
          dbopen();
        };

        DbAccess.DefaultErrorHandler = function (err) {
          $log.log("Default Error Handler -> Error processing SQL: ", err.code + ": " + err.message);
        };

        DbAccess.promisedQuery = function (query, successCB, errorCB) {
          var deferred = $q.defer();
          db.transaction(function (tx) {
            tx.executeSql(query, [], successCB(deferred), errorCB);
          }, errorCB);
          return deferred.promise;
        };

        DbAccess.SingleResultHandler = function (deferred) {
          return function (tx, results) {
            var len = results.rows.length;
            var output_results = [];
            for (var i = 0; i < len; i++) {
              output_results.push(results.rows.item(i));
            }
            deferred.resolve(output_results[0]);
          };
        };

        DbAccess.MultipleResultHandler = function (deferred) {
          console.log('MultipleResultHandler');
          return function (tx, results) {
            var len = results.rows.length;
            var output_results = [];
            for (var i = 0; i < len; i++) {
              output_results.push(results.rows.item(i));
            }
            deferred.resolve(output_results);
          };
        };
        
      }    
  });
  return DbAccess;
};
DbAccess.$inject = ['$q', '$cordovaSQLite', '$ionicPlatform', '$cordovaDevice', '$log'];

var VenuesQueries = function (DbAccess) {
  var VenuesQueries = {
    getVenues: getVenues
  };

  function getVenues(orderBy) {
    if(!orderBy) {
      orderBy = 'expires';
    }
    var query = "SELECT av.id, av.name FROM app_venues av WHERE av.active ORDER BY av.venuename ASC";
    return DbAccess.promisedQuery(query, DbAccess.MultipleResultHandler, DbAccess.DefaultErrorHandler);
  }

  return VenuesQueries;
};
VenuesQueries.$inject = ['DbAccess'];

#2

I solved it.

The problem was: I used 2 different paths.
The entire solution is posted on the plugins page on Github: cordova-plugin-dbcopy