サンプル データベースとテスト スクリプトを作成しました。データベース構造は次のとおりです。
そのための 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}
);
}