OSDN Git Service

968dc8d02d77c6e529bfb3a0b7c2a0c276d50082
[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         //
11         this.syncPHPURL = syncPHPURL;
12         this.isEnabledNetDB = true;
13         //
14         this.callback_updatedNode = null;       // function(nodeinstance){};
15 }
16 MemoryDB.prototype = {
17         UUID_Null: "00000000-0000-0000-0000-000000000000",
18         UUID_NodeType_DecimalNumber: "e3346fd4-ac17-41c3-b3c7-e04972e5c014",
19         UUID_Node_MemoryDBNetworkTimestamp: "a2560a9c-dcf7-4746-ac14-347188518cf2",
20         UUID_Node_MemoryDBNetworkResponseCode: "1eeb6d3d-751f-444f-91c8-ed940e65f8bd",
21         createRequestObject: function(){
22                 var rq = null;
23                 // XMLHttpRequest
24                 try{
25                         // XMLHttpRequest オブジェクトを作成
26                         rq = new XMLHttpRequest();
27                 }catch(e){}
28                 // Internet Explorer
29                 try{
30                         rq = new ActiveXObject('MSXML2.XMLHTTP.6.0');
31                 }catch(e){}
32                 try{
33                         rq = new ActiveXObject('MSXML2.XMLHTTP.3.0');
34                 }catch(e){}
35                 try{
36                         rq = new ActiveXObject('MSXML2.XMLHTTP');
37                 }catch(e){}
38                 if(rq == null){
39                         return null;
40                 }
41                 return rq;
42         },
43         requestObjectDisableCache: function(rq){
44                 //call after open request.
45                 //disable cache
46                 //http://vird2002.s8.xrea.com/javascript/XMLHttpRequest.html
47                 rq.setRequestHeader('Pragma', 'no-cache');                              // HTTP/1.0 における汎用のヘッダフィールド
48                 rq.setRequestHeader('Cache-Control', 'no-cache');               // HTTP/1.1 におけるキャッシュ制御のヘッダフィールド
49                 rq.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT');
50         },
51         sendRequestSync: function(mode, url, data){
52                 //同期モード
53                 var q = this.createRequestObject();
54                 q.open(mode, url, false);
55                 q.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
56                 this.requestObjectDisableCache(q);
57                 try {
58                         q.send(data);
59                 } catch(e){
60                         console.log("sendRequestSync:Network Error.\n");
61                         this.isEnabledNetDB = false;
62                         return null;
63                 }
64                 if(q.status == 0){
65                         console.log("ネットワークにアクセスできません。" + q.status + ":" + q.statusText);
66                 }else if((200 <= q.status && q.status < 300) || (q.status == 304)){
67                         var res = q.responseText;
68                         return res;
69                 } else{
70                         console.log("サーバーがエラーを返しました。" + request.status + ":" + request.statusText);
71                 }
72                 this.isEnabledNetDB = false;
73                 return null;
74         },
75         syncDB: function(){
76                 // MySQLと同期
77                 // 定期的に呼び出されることを想定
78                 var r, a, d;
79                 if(this.root.length == 0){
80                         // 初回同期時は全て取得
81                         r = this.sendRequestSync("GET", this.syncPHPURL + "?action=getallnode", null);
82                 } else{
83                         // 差分のみを取得
84                         d = this.getNodeFromUUID(this.UUID_Node_MemoryDBNetworkTimestamp).identifier;
85                         r = this.sendRequestSync("GET", this.syncPHPURL + "?action=getnodemod&t=" + d, null);
86                 }
87                 a = r.split("\n");
88                 for(var i = 0, iLen = a.length; i < iLen; i++){
89                         try{
90                                 d = eval(a[i]);
91                         } catch(e){
92                                 console.log(i + ": " + e + "\n");
93                                 continue;
94                         }
95                         if(d === undefined){
96                                 continue;
97                         }
98                         this.updateNodeInternal(d[2], d[1], d[0]);
99                 }
100                 //console.log(this.root);
101         },
102         updateNode: function(ident, tid, nid){
103                 // 該当タグのデータを書き換え、もしくは新規作成する。
104                 // 可能であればネットワークに反映する
105                 // nid(nodeid)は省略可能で、省略時は新たなUUIDが自動的に付与される
106                 // tid(typeid)も省略可能で、省略時はNullUUIDが付与される。
107                 // identはnullもしくは空文字でもかまわない。
108                 // 戻り値はMemoryDBNodeTagインスタンス
109                 // エラー発生時はundefinedを返す。
110                 this.updateNodeInternal(ident, tid, nid, true);
111         },
112         updateNodeInternal: function(ident, tid, nid, enableSync){
113                 // 基本的にローカルデータのみ変更
114                 // enableSync == trueでネットワーク同期する
115                 var t, s, r;
116                 if(!tid){
117                         tid = this.UUID_Null;
118                 }
119                 if(!nid){
120                         nid = this.createUUID();
121                 }
122                 // 存在確認
123                 t = this.getNodeFromUUID(nid);
124                 if(t){
125                         // 変更
126                         t.typeid = tid;
127                         t.identifier = ident;
128                         if(enableSync && this.isEnabledNetDB){
129                                 s = this.syncPHPURL + "?action=updatenode";
130                                 s += "&nid=" + encodeURIComponent(nid);
131                                 s += "&tid=" + encodeURIComponent(tid);
132                                 s += "&ident=" + encodeURIComponent(ident);
133                                 r = this.sendRequestSync("GET", s, null);
134                                 //console.log(r);
135                         }
136                 } else{
137                         // 新規作成
138                         t = new MemoryDBNodeTag(nid, tid, ident);
139                         this.root.push(t);
140                         this.nodeList.push(t);
141                         if(enableSync && this.isEnabledNetDB){
142                                 s = this.syncPHPURL + "?action=addnode";
143                                 s += "&nid=" + encodeURIComponent(nid);
144                                 s += "&tid=" + encodeURIComponent(tid);
145                                 s += "&ident=" + encodeURIComponent(ident);
146                                 r = this.sendRequestSync("GET", s, null);
147                                 //console.log(r);
148                         }
149                 }
150                 if(this.callback_updatedNode){
151                         this.callback_updatedNode(t);
152                 }
153         },
154         createUUID: function(){
155                 var f = this.createUUIDSub;
156                 return (f() + f() + "-" + f() + "-" + f() + "-" + f() + "-" + f() + f() + f());
157         },
158         createUUIDSub: function(){
159                 return (((1 + Math.random()) * 0x10000) | 0).toString(16).toLowerCase().substring(1);
160         },
161         getNodeFromUUID: function(nodeid){
162                 return this.nodeList.isIncluded(nodeid, function(a, b){ return a.nodeid == b; });
163         },
164 }
165
166 function MemoryDBNodeTag(nodeid, typeid, identifier){
167         this.nodeid = nodeid;
168         this.typeid = typeid;
169         this.identifier = identifier;
170         //
171 }
172 MemoryDBNodeTag.prototype = {
173
174 }
175
176 function MemoryDBEdgeTag(typeUUIDStr){
177         this.uuid = null;
178 }
179 MemoryDBEdgeTag.prototype = {
180
181 }