1useEffect(()=>2{3if(!inited)//开发模式下这个useEffect将执行两次4{5setInited(true);6window.myObjUnit={};7window.mySQLWorker2=newWorker("worker.sql-wasm.js");//这个从dist中加载,在worker线程中运行8constworker2=window.mySQLWorker2;9worker2.onerror=e=>console.log("Worker2 error: ",e);10worker2.postMessage({//通知worker线程启动数据库11id:1,12action:"open",13//buffer:buf, /*Optional. An ArrayBuffer representing an SQLite Database file*/可用来加载已有的数据库,否则将建立新的数据库14});1516worker2.onmessage=()=>{17console.log("Database opened");//启动成功18worker2.onmessage=event=>{19console.log(event.data);//The result of the query20};2122worker2.postMessage({23id:2,24action:"exec",25sql:"CREATE TABLE test (id char, age int, name char);",//建表26//params: { "$id": 1 }27});28};29}3031},[]);//初始化数据库
执行后的Chrome控制台输出:
2、worker模式插入和查询数据
1functionaddUnit(){2if(window.myObjUnit)3{4varunitid="unit_"+countUnit;5window.myObjUnit[unitid]={id:unitid};6setCountUnit(countUnit+1);//命名序列加一78constworker=window.mySQLWorker2;9worker.postMessage({//顺序发送指令10id:2,11action:"exec",12sql:"INSERT INTO test VALUES ($id,$age,$name)",13params:{"$id":unitid,"$age":1,"$name":unitid}14});1516worker.postMessage({17id:2,18action:"exec",19sql:"SELECT id,age,name FROM test",20//params: { "$id": 1 }21});2223}24}//添加一条记录
点击两次“添加单位”后,Chrome控制台的输出:
可以看到插入的两条数据以及select语句返回的数据结构。
3、worker模式导出数据库
改造一下页面:
如图向worker线程发送export命令
再改造一下主线程的onmessage响应:
1worker2.onmessage=event=>{2if(event.data.id==2)3{4console.log(event.data);//The result of the query5}6elseif(event.data.id=="export2")7{//如果这个信息的id是export28varblob=newBlob([event.data.buffer],{type:"application/geopackage+sqlite3"});9varlink=document.createElement("a");//则用超链接方式下载这个数据库文件10link.href=window.URL.createObjectURL(blob);11link.download="test.db";12link.click();13window.URL.revokeObjectURL(blob);14}15};
1functionexportDB(){2varconfig={3locateFile:file=>"sql-wasm.wasm"4}5initSqlJs(config).then(function(SQL){//虽然这里调用的是worker.sql-wasm.js中的initSqlJs方法,但仍然运行在主线程中!6vardb=newSQL.Database();//建库7//Run a query without reading the results8db.run("CREATE TABLE test (col1, col2);");9//Insert two rows: (1,111) and (2,222)10db.run("INSERT INTO test VALUES (?,?), (?,?)",[1,111,2,222]);11//Prepare a statement12varstmt=db.prepare("SELECT * FROM test WHERE col1 BETWEEN $start AND $end");13stmt.getAsObject({$start:1,$end:1});//{col1:1, col2:111}1415//Bind new values16stmt.bind({$start:1,$end:2});17while(stmt.step()){//18varrow=stmt.getAsObject();19console.log(Here is a row:+JSON.stringify(row));20}21//var fs = require("fs");22vardata=db.export();//这个data与worker2.onmessage返回的event.data是一样的!23//var buffer = new Buffer(data);24varblob=newBlob([data.buffer],{type:"application/geopackage+sqlite3"});25//fs.writeFileSync("filename.sqlite", buffer);26varlink=document.createElement("a");27link.href=window.URL.createObjectURL(blob);28link.download="test.db";29link.click();30window.URL.revokeObjectURL(blob);3132//var w=new File3334});
1functiontestImportDB(Uints){23//测试主线程方式4varconfig={5locateFile:file=>"sql-wasm.wasm"6}7initSqlJs(config).then(function(SQL){8vardb=newSQL.Database(Uints);9db.run("INSERT INTO test VALUES (?,?,?)",["unitid",1,"unitid"]);10//Prepare a statement11varstmt=db.prepare("SELECT * FROM test ");12while(stmt.step()){//13varrow=stmt.getAsObject();14console.log(Here is a row:+JSON.stringify(row));15}16});17//测试worker线程方式18constworker3=newWorker("worker.sql-wasm.js");19worker3.postMessage({20id:1,21action:"open",22buffer:Uints,23});24worker3.onmessage=()=>{25console.log("Database opened");26worker3.onmessage=event=>{27console.log(event.data);//The result of the query28};2930worker3.postMessage({31id:2,32action:"exec",33sql:"INSERT INTO test VALUES ($id,$age,$name)",34params:{"$id":"unitid","$age":1,"$name":"unitid"}35});3637worker3.postMessage({38id:2,39action:"exec",40sql:"SELECT id,age,name FROM test",41//params: { "$id": 1 }42});43};44}