OSDN Git Service

エッジの同期を追加。まだ不完全。
[chnosproject/AI004.git] / memdb / memdb.js
1 // 知識表現のデータベース
2 // php経由でMySQLデータベースに同期する機能と
3 // データへのアクセスを提供する
4
5 function MemoryDB(syncPHPURL){
6         // 全データ
7         this.root = new Array();
8         //
9         this.nodeList = new Array();
10         this.edgeList = new Array();
11         //
12         this.syncPHPURL = syncPHPURL;
13         this.isEnabledNetDB = true;
14         //
15         this.callback_updatedNode = null;       // function(nodeInstance){};
16         this.callback_updatedEdge = null;       // function(edgeInstance){};
17 }
18 MemoryDB.prototype = {
19         UUID_Null: "00000000-0000-0000-0000-000000000000",
20         UUID_NodeType_DecimalNumber: "e3346fd4-ac17-41c3-b3c7-e04972e5c014",
21         UUID_Node_MemoryDBNetworkTimestamp: "a2560a9c-dcf7-4746-ac14-347188518cf2",
22         UUID_Node_MemoryDBNetworkResponseCode: "1eeb6d3d-751f-444f-91c8-ed940e65f8bd",
23         createRequestObject: function(){
24                 var rq = null;
25                 // XMLHttpRequest
26                 try{
27                         // XMLHttpRequest オブジェクトを作成
28                         rq = new XMLHttpRequest();
29                 }catch(e){}
30                 if(rq){
31                         return rq;
32                 }
33                 // Internet Explorer
34                 try{
35                         rq = new ActiveXObject('MSXML2.XMLHTTP.6.0');
36                 }catch(e){}
37                 if(rq){
38                         return rq;
39                 }
40                 try{
41                         rq = new ActiveXObject('MSXML2.XMLHTTP.3.0');
42                 }catch(e){}
43                 if(rq){
44                         return rq;
45                 }
46                 try{
47                         rq = new ActiveXObject('MSXML2.XMLHTTP');
48                 }catch(e){}
49                 if(rq){
50                         return rq;
51                 }
52                 return null;
53         },
54         requestObjectDisableCache: function(rq){
55                 //call after open request.
56                 //disable cache
57                 //http://vird2002.s8.xrea.com/javascript/XMLHttpRequest.html
58                 rq.setRequestHeader('Pragma', 'no-cache');                              // HTTP/1.0 における汎用のヘッダフィールド
59                 rq.setRequestHeader('Cache-Control', 'no-cache');               // HTTP/1.1 におけるキャッシュ制御のヘッダフィールド
60                 rq.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT');
61         },
62         sendRequestSync: function(mode, url, data){
63                 //同期モード
64                 var q = this.createRequestObject();
65                 q.open(mode, url, false);
66                 q.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
67                 this.requestObjectDisableCache(q);
68                 try {
69                         q.send(data);
70                 } catch(e){
71                         console.log("sendRequestSync:Network Error.\n");
72                         this.isEnabledNetDB = false;
73                         return null;
74                 }
75                 if(q.status == 0){
76                         console.log("ネットワークにアクセスできません。" + q.status + ":" + q.statusText);
77                 }else if((200 <= q.status && q.status < 300) || (q.status == 304)){
78                         var res = q.responseText;
79                         return res;
80                 } else{
81                         console.log("サーバーがエラーを返しました。" + request.status + ":" + request.statusText);
82                 }
83                 this.isEnabledNetDB = false;
84                 return null;
85         },
86         syncDB: function(){
87                 // MySQLと同期
88                 // 定期的に呼び出されることを想定
89                 this.syncDBNode();
90                 this.syncDBEdge();
91         },
92         syncDBNode: function(){
93                 var r, a, d;
94                 if(this.nodeList.length == 0){
95                         // 初回同期時は全て取得
96                         r = this.sendRequestSync("GET", this.syncPHPURL + "?action=getallnode", null);
97                 } else{
98                         // 差分のみを取得
99                         d = this.getNodeFromUUID(this.UUID_Node_MemoryDBNetworkTimestamp).identifier;
100                         r = this.sendRequestSync("GET", this.syncPHPURL + "?action=getallnodemod&t=" + d, null);
101                 }
102                 a = r.split("\n");
103                 for(var i = 0, iLen = a.length; i < iLen; i++){
104                         try{
105                                 d = eval(a[i]);
106                         } catch(e){
107                                 console.log(i + ": " + e + "\n");
108                                 continue;
109                         }
110                         if(d === undefined){
111                                 continue;
112                         }
113                         this.updateNodeInternal(d[2], d[1], d[0]);
114                 }
115         },
116         syncDBEdge: function(){
117                 var r, a, d;
118                 if(this.edgeList.length == 0){
119                         // 初回同期時は全て取得
120                         r = this.sendRequestSync("GET", this.syncPHPURL + "?action=getalledge", null);
121                 } else{
122                         // 差分のみを取得
123                         /*
124                         d = this.getNodeFromUUID(this.UUID_Node_MemoryDBNetworkTimestamp).identifier;
125                         r = this.sendRequestSync("GET", this.syncPHPURL + "?action=getallnodemod&t=" + d, null);
126                         */
127                         return;
128                 }
129                 a = r.split("\n");
130                 for(var i = 0, iLen = a.length; i < iLen; i++){
131                         try{
132                                 d = eval(a[i]);
133                         } catch(e){
134                                 console.log(i + ": " + e + "\n");
135                                 continue;
136                         }
137                         if(d === undefined){
138                                 continue;
139                         }
140                         if(     d[0] != this.UUID_Node_MemoryDBNetworkTimestamp &&
141                                 d[0] != this.UUID_Node_MemoryDBNetworkResponseCode){
142                                 // edge data
143                                 this.updateEdgeInternal(d[2], d[3], d[1], d[0]);
144                         } else{
145                                 // node data
146                                 this.updateNodeInternal(d[2], d[1], d[0]);
147                         }
148                 }
149         },
150         updateNode: function(ident, tid, nid){
151                 // 該当タグのデータを書き換え、もしくは新規作成する。
152                 // 可能であればネットワークに反映する
153                 // nid(nodeid)は省略可能で、省略時は新たなUUIDが自動的に付与される
154                 // tid(typeid)も省略可能で、省略時はNullUUIDが付与される。
155                 // identはnullもしくは空文字でもかまわない。
156                 // 戻り値はMemoryDBNodeTagインスタンス
157                 // エラー発生時はundefinedを返す。
158                 this.updateNodeInternal(ident, tid, nid, true);
159         },
160         updateNodeInternal: function(ident, tid, nid, enableSync){
161                 // 基本的にローカルデータのみ変更
162                 // enableSync == trueでネットワーク同期する
163                 var t, s, r;
164                 if(!tid){
165                         tid = this.UUID_Null;
166                 }
167                 if(!nid){
168                         nid = this.createUUID();
169                 }
170                 // 存在確認
171                 t = this.getNodeFromUUID(nid);
172                 if(t){
173                         // 変更
174                         t.typeid = tid;
175                         t.identifier = ident;
176                         if(enableSync && this.isEnabledNetDB){
177                                 s = this.syncPHPURL + "?action=updatenode";
178                                 s += "&nid=" + encodeURIComponent(nid);
179                                 s += "&tid=" + encodeURIComponent(tid);
180                                 s += "&ident=" + encodeURIComponent(ident);
181                                 r = this.sendRequestSync("GET", s, null);
182                                 //console.log(r);
183                         }
184                 } else{
185                         // 新規作成
186                         t = new MemoryDBNodeTag(nid, tid, ident);
187                         this.root.push(t);
188                         this.nodeList.push(t);
189                         if(enableSync && this.isEnabledNetDB){
190                                 s = this.syncPHPURL + "?action=addnode";
191                                 s += "&nid=" + encodeURIComponent(nid);
192                                 s += "&tid=" + encodeURIComponent(tid);
193                                 s += "&ident=" + encodeURIComponent(ident);
194                                 r = this.sendRequestSync("GET", s, null);
195                                 //console.log(r);
196                         }
197                 }
198                 if(this.callback_updatedNode){
199                         this.callback_updatedNode(t);
200                 }
201         },
202         updateEdge: function(nid0, nid1, tid, eid){
203                 // 該当タグのデータを書き換え、もしくは新規作成する。
204                 // 可能であればネットワークに反映する
205                 // eid(nodeid)は省略可能で、省略時は新たなUUIDが自動的に付与される
206                 // tid(typeid)も省略可能で、省略時はNullUUIDが付与される
207                 // 戻り値はMemoryDBEdgeTagインスタンス
208                 // エラー発生時はundefinedを返す。
209                 this.updateEdgeInternal(nid0, nid1, tid, eid, true);
210         },
211         updateEdgeInternal: function(nid0, nid1, tid, eid, enableSync){
212                 // 基本的にローカルデータのみ変更
213                 // enableSync == trueでネットワーク同期する
214                 var t, s, r;
215                 if(!tid){
216                         tid = this.UUID_Null;
217                 }
218                 if(!eid){
219                         eid = this.createUUID();
220                 }
221                 // 存在確認
222                 t = this.getEdgeFromUUID(eid);
223                 if(t){
224                         // 変更
225                         /*
226                         t.typeid = tid;
227                         t.identifier = ident;
228                         if(enableSync && this.isEnabledNetDB){
229                                 s = this.syncPHPURL + "?action=updatenode";
230                                 s += "&nid=" + encodeURIComponent(nid);
231                                 s += "&tid=" + encodeURIComponent(tid);
232                                 s += "&ident=" + encodeURIComponent(ident);
233                                 r = this.sendRequestSync("GET", s, null);
234                                 //console.log(r);
235                         }
236                         */
237                         return;
238                 } else{
239                         // 新規作成
240                         t = new MemoryDBEdgeTag(eid, tid, nid0, nid1);
241                         this.root.push(t);
242                         this.edgeList.push(t);
243                         if(enableSync && this.isEnabledNetDB){
244                                 s = this.syncPHPURL + "?action=addedge";
245                                 s += "&eid=" + encodeURIComponent(eid);
246                                 s += "&tid=" + encodeURIComponent(tid);
247                                 s += "&nid0=" + encodeURIComponent(nid0);
248                                 s += "&nid1=" + encodeURIComponent(nid1);
249                                 r = this.sendRequestSync("GET", s, null);
250                                 console.log(r);
251                         }
252                 }
253                 if(this.callback_updatedEdge){
254                         this.callback_updatedEdge(t);
255                 }
256         },
257         createUUID: function(){
258                 var f = this.createUUIDSub;
259                 return (f() + f() + "-" + f() + "-" + f() + "-" + f() + "-" + f() + f() + f());
260         },
261         createUUIDSub: function(){
262                 return (((1 + Math.random()) * 0x10000) | 0).toString(16).toLowerCase().substring(1);
263         },
264         getNodeFromUUID: function(nodeid){
265                 return this.nodeList.isIncluded(nodeid, function(a, b){ return a.nodeid == b; });
266         },
267         getEdgeFromUUID: function(edgeid){
268                 return this.edgeList.isIncluded(edgeid, function(a, b){ return a.edgeid == b; });
269         },
270 }
271
272 function MemoryDBNodeTag(nodeid, typeid, identifier){
273         this.nodeid = nodeid;
274         this.typeid = typeid;
275         this.identifier = identifier;
276         //
277 }
278 MemoryDBNodeTag.prototype = {
279
280 }
281
282 function MemoryDBEdgeTag(edgeid, typeid, nodeid0, nodeid1){
283         this.edgeid = edgeid;
284         this.typeid = typeid;
285         this.nodeid0 = nodeid0;
286         this.nodeid1 = nodeid1;
287 }
288 MemoryDBEdgeTag.prototype = {
289
290 }