0

サンプル データベースとテスト スクリプトを作成しました。データベース構造は次のとおりです。

ここに画像の説明を入力

そのための JSFiddle を作成しました: fiddle 上部のストレス テスト以外のすべてのボタンをクリックしてから、テストをクリックします。

問題は、プロバイダー webSql では完全に機能しますが、プロバイダー indexedDb では失敗することです。プロ パッケージをダウンロードしたところ、テスト 3 が部分的に機能するようになりましたが、テスト 2 ではまだ完全に失敗しています。私が見つけた問題は、結合関係を使用してデータベースにクエリを実行したときです(例:department.IDが1の従業員)indexedDbはこのリクエストを処理できません。

どうすればこの状況を回避できますか?

コード全体は次のとおりです。

index.html:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
  <script src="jaydataPro/jaydata.min.js"></script>
  <script src="jaydataPro/jaydataproviders/IndexedDbProProvider.min.js"></script>
  <script src="jaydataPro/jaydataproviders/SqLiteProProvider.min.js"></script>
  <script src="jaydataPro/jaydataproviders/WebApiProvider.min.js"></script>
  <script src="jaydataPro/jaydataproviders/YQLProvider.min.js"></script>
  <script src="sampledatabase.js"></script>
  <script src="test.js"></script>
  <title>Jaydata Test</title>
</head>

<body>
  <div>
    <h3>Database Generation</h3>
    <div>
      <button onclick="TestAddDepartments(5);">Add Departments</button>
    </div>
    <div>
      <button onclick="AddEmployeeList(TestEmployeeList(1,100),1);"> Employees 1</button>
      <button onclick="AddEmployeeList(TestEmployeeList(101,100),2);">Employees 2</button>
      <button onclick="AddEmployeeList(TestEmployeeList(201,100),3);">Employees 3</button>
      <button onclick="AddEmployeeList(TestEmployeeList(301,100),4);">Employees 4</button>
      <button onclick="AddEmployeeList(TestEmployeeList(401,100),5);">Employees 5</button>
    </div>
    <div>
      <button onclick="AddStockList(TestStockList(1,400),1);">
      Stocks 1</button>
      <button onclick="AddStockList(TestStockList(401,400),2);">
      Stocks 2</button>
      <button onclick="AddStockList(TestStockList(801,400),3);">
      Stocks 3</button>
      <button onclick="AddStockList(TestStockList(1201,400),4);">
      Stocks 4</button>
      <button onclick="AddStockList(TestStockList(1601,400),5);">
      Stocks 5</button>
    </div>
    <div>
      <button onclick="AddStockList(TestStockList(2001,5000),2);">
      Stress Test for Test 3</button>
    </div>
  </div>
  <div>
    <h3>Queries</h3>
      <button onclick="TestSearchEmployeeName1()">Test 1</button>
      <button onclick="TestSearchEmployeeName2()">Test 2</button>
      <button onclick="TestSearchEmployeeName3()">Test 3</button>
  </div>
  <div>
    <h3>Results</h3>
    <p id='Result'>Result</p>
  </div>
</body>
</html>

サンプルデータベース.js:

/*
  x is a database
  Database name is Company
  Company has 3 tables:
    =Departments
      -ID(key,computed)
      -DepartmentName(string,required)
    =Employees
      -ID(key,computed)
      -Name(string,required)
    =Stocks
      -ID(key,computed)
      -Description(string)
      -NumItems(int,required)
  Employee is connected to Department
  Stock is connected to Department
  Department has a list of Stocks and Employees
To do:
  -insert websql and indexeddb translations to the document
*/



$data.Entity.extend("Org.Employee",{
  ID: {key: true, type: "integer", computed: true},
  Name: {type: "string", required: true},
  Department: {type: "Org.Department", inverseProperty: "Employees"}
});

$data.Entity.extend("Org.Stock",{
  ID: {key: true, type: "integer", computed: true},
  Description: {type: "string"},
  NumItems: {type: "integer", required: true},
  Department: {type: "Org.Department", inverseProperty: "Stocks"}
});

$data.Entity.extend("Org.Department",{
  ID: {key: true, type: "integer", computed: true},
  DepartmentName: {type: "string", required: true},
  Employees:{type: Array, elementType: "Org.Employee", inverseProperty:"Department"},
  Stocks:{type: Array, elementType: "Org.Stock", inverseProperty:"Department"}
});

$data.EntityContext.extend("Company",{
  Employees: {type: $data.EntitySet, elementType: Org.Employee},
  Departments: {type: $data.EntitySet, elementType: Org.Department},
  Stocks: {type: $data.EntitySet, elementType: Org.Stock}
});

var x= new Company({
  provider: "indexedDb",
  databaseName: "DB",
  version: 1,
  dbCreation: $data.storageProviders.DbCreationType.DropAllExistingTables
});

function AddEmployee(emp,department)
{
  x.Departments.first(
    function(it){
      return it.ID==department.valueOf()
    }, 
    {emp:emp,department:department}, 
    function(dep){
      x.Departments.attach(dep);
      emp.Department=dep;
      x.Employees.add(emp);
      x.Employees.saveChanges();
    }
  );
}

function RemoveEmployee(emp_id)
{
  x.Employees.first(
    function(res){
      return res.ID==emp_id.valueOf();
    },
    {emp_id:emp_id},
    function(emp)
    {
      x.Employees.remove(emp);
      x.Employees.saveChanges();
    }
  );  
}

function ChangeEmployeeName(emp_id,new_name)
{
  x.Employees.first(
    function(res){
      return res.ID==emp_id.valueOf();
    },
    {emp_id:emp_id,new_name:new_name},
    function(emp)
    {
      x.Employees.attach(emp);
      emp.Name=new_name;
      x.Employees.saveChanges();
    }
  );
}

function RemoveDepartment(dep_id)
{
  x.Employees.filter(
    function(res){
      return res.Department.ID==dep_id
    },
    {dep_id:dep_id}
  ).forEach(
    function(it){
      x.Employees.remove(it)
    });
  x.Employees.saveChanges();
  x.Departments.first(
    function(it)
    {
      return it.ID==dep_id;
    },
    {dep_id:dep_id},
    function(dep)
    {
      x.Departments.remove(dep);
      x.Departments.saveChanges();
    }
  );
}

function AddStock(stock,department)
{
  x.Departments.first(
    function(it){
      return it.ID==department.valueOf()}, 
      {emp:emp,department:department}, 
      function(dep){
        x.Departments.attach(dep);
        stock.Department=dep;
        x.Stocks.add(stock);
        x.Stocks.saveChanges();
      });
}

function AddEmployeeList(list,department)
{
  x.Departments.first(
    function(it){return it.ID==department.valueOf()}, 
    {department:department,list:list}, 
    function(dep){
      for (var i = 0; i < list.length; i++) {
        list[i].Department=dep;
      };
      x.Departments.attach(dep);
      x.Employees.addMany(list);
      x.Employees.saveChanges();
    });
}

function AddStockList(list,department)
{
  x.Departments.first(
    function(it){return it.ID==department.valueOf()}, 
    {department:department,list:list}, 
    function(dep){
      for (var i = 0; i < list.length; i++) {
        list[i].Department=dep;
      };
      x.Departments.attach(dep);
      x.Stocks.addMany(list);
      x.Stocks.saveChanges();
    });
}

test.js:

//testing script

function TestAddDepartments(number)   //number of departments
{
  var dep='Department';
  for (var i = 1; i <= number.valueOf(); i++)
  {
    var temp=dep+i.toString();
    x.Departments.add({DepartmentName:temp});
  };
  x.Departments.saveChanges();
}

function TestEmployeeList(start,number)
{
  emp_list=new Array();
  var emp='Employee';
  for (var i = start.valueOf(); i < start.valueOf()+number.valueOf(); i++)
  {
    var temp=emp+i.toString();
    emp_list.push({Name:temp});
  };
  return emp_list;
}

function TestStockList(start,number)
{
  stock_list=new Array();
  var stock='Stock';
  for (var i = start.valueOf(); i < start.valueOf()+number.valueOf(); i++)
  {
    var temp=stock+i.toString();
    var num=Math.floor((Math.random()*1000)+1);
    stock_list.push({Description:temp,NumItems:num});
  };
  return stock_list;
}

/*function TestSearchEmployeeName(number,limit)
{
  var start= new Date().getTime();
  var emp='Employee';
  for (var i = 1; i <= number.valueOf(); i++)
  {
    num=Math.floor((Math.random()*limit.valueOf())+1);
    search=emp+num.toString();
    x.Employees.filter(
      function(res)
      {
        return res.Name==search;
      }).
    forEach(
      function(it)
      {
        console.log(it.Name);
      });
  };
  var elapsed=new Date().getTime()-start;
  console.log("Searching the database with "+number.toString()+
    " entries took "+elapsed.toString()+" milliseconds");
}
*/

//Static tests
function TestSearchEmployeeName1()
{
  var start= new Date().getTime();
  x.Employees.filter(
    function(res)
    {
      return res.Name=='Employee43';
    },{start:start}).
  toArray(function(it){
    var elapsed=new Date().getTime()-start;
    var res="Query with "+it.length.toString()+" result took "+
      elapsed.toString()+" milliseconds";
    document.getElementById('Result').innerHTML = res;
  },{start:start}
  );
}

function TestSearchEmployeeName2()
{
  var start= new Date().getTime();
  x.Employees.filter(
    function(res)
    {
      return res.Department.ID==1;
    },{start:start}).
  toArray(function(it){
    var elapsed=new Date().getTime()-start;
    var res="Query with "+it.length.toString()+" results took "+
      elapsed.toString()+" milliseconds";
    document.getElementById('Result').innerHTML = res;
  },{start:start}
  );
}

function TestSearchEmployeeName3()
{
  var start= new Date().getTime();
  x.Stocks.filter(
    function(res)
    {
      return res.NumItems>258 || res.Department.ID<3;
    },{start:start}).
  toArray(function(it){
    var elapsed=new Date().getTime()-start;
    var res="Query with "+it.length.toString()+" results took "+
      elapsed.toString()+" milliseconds";
    document.getElementById('Result').innerHTML = res;
  },{start:start}
  );
}
4

1 に答える 1

3

プロバイダー機能マトリックスによると、include() および複合型マッピング機能は IndexedDB にはまだ実装されていません。つまり、IndexedDB ではナビゲーション プロパティを使用できず、SQLite/WebSQL でのみ使用できます。この機能は、ユーザーの声ページで提案できます。

于 2013-07-01T10:59:06.853 に答える