xoslib wip
[plstackapi.git] / planetstack / core / xoslib / static / xsh / shell_utils.js
1 DB = function() {
2 }
3
4 print = function(msg) {
5   //console.log(msg);
6 }
7
8
9 friendlyEqual = function( a , b ){
10     if ( a == b )
11         return true;
12
13     if ( tojson( a ) == tojson( b ) )
14         return true;
15
16     return false;
17 }
18
19
20 doassert = function( msg ){
21     print( "assert: " + msg );
22     throw msg;
23 }
24
25 assert = function( b , msg ){
26     if ( assert._debug && msg ) print( "in assert for: " + msg );
27
28     if ( b )
29         return;
30     
31     doassert( "assert failed : " + msg );
32 }
33
34 assert.eq = function( a , b , msg ){
35     if ( assert._debug && msg ) print( "in assert for: " + msg );
36
37     if ( a == b )
38         return;
39
40     if ( ( a != null && b != null ) && friendlyEqual( a , b ) )
41         return;
42
43     doassert( "[" + tojson( a ) + "] != [" + tojson( b ) + "] are not equal : " + msg );
44 }
45
46 assert.neq = function( a , b , msg ){
47     if ( assert._debug && msg ) print( "in assert for: " + msg );
48     if ( a != b )
49         return;
50
51     doassert( "[" + a + "] != [" + b + "] are equal : " + msg );
52 }
53
54 assert.soon = function( f, msg, timeout, interval ) {
55     if ( assert._debug && msg ) print( "in assert for: " + msg );
56
57     var start = new Date();
58     timeout = timeout || 30000;
59     interval = interval || 200;
60     var last;
61     while( 1 ) {
62         
63         if ( typeof( f ) == "string" ){
64             if ( eval( f ) )
65                 return;
66         }
67         else {
68             if ( f() )
69                 return;
70         }
71         
72         if ( ( new Date() ).getTime() - start.getTime() > timeout )
73             doassert( "assert.soon failed: " + f + ", msg:" + msg );
74         sleep( interval );
75     }
76 }
77
78 assert.throws = function( func , params , msg ){
79     if ( assert._debug && msg ) print( "in assert for: " + msg );
80     try {
81         func.apply( null , params );
82     }
83     catch ( e ){
84         return e;
85     }
86
87     doassert( "did not throw exception: " + msg );
88 }
89
90 assert.commandWorked = function( res , msg ){
91     if ( assert._debug && msg ) print( "in assert for: " + msg );
92
93     if ( res.ok == 1 )
94         return;
95     
96     doassert( "command failed: " + tojson( res ) + " : " + msg );
97 }
98
99 assert.commandFailed = function( res , msg ){
100     if ( assert._debug && msg ) print( "in assert for: " + msg );
101
102     if ( res.ok == 0 )
103         return;
104     
105     doassert( "command worked when it should have failed: " + tojson( res ) + " : " + msg );
106 }
107
108 assert.isnull = function( what , msg ){
109     if ( assert._debug && msg ) print( "in assert for: " + msg );
110
111     if ( what == null )
112         return;
113     
114     doassert( "supposed to null (" + ( msg || "" ) + ") was: " + tojson( what ) );
115 }
116
117 assert.lt = function( a , b , msg ){
118     if ( assert._debug && msg ) print( "in assert for: " + msg );
119
120     if ( a < b )
121         return;
122     doassert( a + " is not less than " + b + " : " + msg );
123 }
124
125 assert.gt = function( a , b , msg ){
126     if ( assert._debug && msg ) print( "in assert for: " + msg );
127
128     if ( a > b )
129         return;
130     doassert( a + " is not greater than " + b + " : " + msg );
131 }
132
133 Object.extend = function( dst , src , deep ){
134     for ( var k in src ){
135         var v = src[k];
136         if ( deep && typeof(v) == "object" ){
137             v = Object.extend( typeof ( v.length ) == "number" ? [] : {} , v , true );
138         }
139         dst[k] = v;
140     }
141     return dst;
142 }
143
144 argumentsToArray = function( a ){
145     var arr = [];
146     for ( var i=0; i<a.length; i++ )
147         arr[i] = a[i];
148     return arr;
149 }
150
151 isString = function( x ){
152     return typeof( x ) == "string";
153 }
154
155 isNumber = function(x){
156     return typeof( x ) == "number";
157 }
158
159 isObject = function( x ){
160     return typeof( x ) == "object";
161 }
162
163 String.prototype.trim = function() {
164     return this.replace(/^\s+|\s+$/g,"");
165 }
166 String.prototype.ltrim = function() {
167     return this.replace(/^\s+/,"");
168 }
169 String.prototype.rtrim = function() {
170     return this.replace(/\s+$/,"");
171 }
172
173 Date.timeFunc = function( theFunc , numTimes ){
174
175     var start = new Date();
176     
177     numTimes = numTimes || 1;
178     for ( var i=0; i<numTimes; i++ ){
179         theFunc.apply( null , argumentsToArray( arguments ).slice( 2 ) );
180     }
181
182     return (new Date()).getTime() - start.getTime();
183 }
184
185 Date.prototype.tojson = function(){
186     return "\"" + this.toString() + "\"";
187 }
188
189 RegExp.prototype.tojson = RegExp.prototype.toString;
190
191 Array.contains = function( a  , x ){
192     for ( var i=0; i<a.length; i++ ){
193         if ( a[i] == x )
194             return true;
195     }
196     return false;
197 }
198
199 Array.unique = function( a ){
200     var u = [];
201     for ( var i=0; i<a.length; i++){
202         var o = a[i];
203         if ( ! Array.contains( u , o ) ){
204             u.push( o );
205         }
206     }
207     return u;
208 }
209
210 Array.shuffle = function( arr ){
211     for ( var i=0; i<arr.length-1; i++ ){
212         var pos = i+Math.floor(Math.random()*(arr.length-i));
213         var save = arr[i];
214         arr[i] = arr[pos];
215         arr[pos] = save;
216     }
217     return arr;
218 }
219
220
221 Array.tojson = function( a , indent , x , html){
222     if (!indent) 
223         indent = "";
224     var spacer = "";
225     if(html) {
226       spacer = "<br/>";
227       indent = " &nbsp; "
228     }
229
230     var s = spacer + "[ " + spacer;
231     indent += " ";
232     for ( var i=0; i<a.length; i++){
233         s += indent + tojson( a[i], indent );
234         if ( i < a.length - 1 ){
235             s += "," + spacer;
236         }
237     }
238     if ( a.length == 0 ) {
239         s += indent;
240     }
241
242     indent = indent.substring(1);
243     s += spacer + " "+"]";
244     return s;
245 }
246
247 Array.fetchRefs = function( arr , coll ){
248     var n = [];
249     for ( var i=0; i<arr.length; i ++){
250         var z = arr[i];
251         if ( coll && coll != z.getCollection() )
252             continue;
253         n.push( z.fetch() );
254     }
255     
256     return n;
257 }
258
259 Array.sum = function( arr ){
260     if ( arr.length == 0 )
261         return null;
262     var s = arr[0];
263     for ( var i=1; i<arr.length; i++ )
264         s += arr[i];
265     return s;
266 }
267
268 Array.avg = function( arr ){
269     if ( arr.length == 0 )
270         return null;
271     return Array.sum( arr ) / arr.length;
272 }
273
274 Array.stdDev = function( arr ){
275     var avg = Array.avg( arr );
276     var sum = 0;
277
278     for ( var i=0; i<arr.length; i++ ){
279         sum += Math.pow( arr[i] - avg , 2 );
280     }
281
282     return Math.sqrt( sum / arr.length );
283 }
284
285 if ( ! ObjectId.prototype )
286     ObjectId.prototype = {}
287
288 ObjectId.prototype.toString = function(){
289     return this.str;
290 }
291
292 ObjectId.prototype.tojson = function(){
293     return "ObjectId(\"" + this.str + "\")";
294 }
295
296 ObjectId.prototype.isObjectId = true;
297
298 tojson = function( x, indent , nolint , html){
299     if ( x == null )
300         return "null";
301     
302     if ( x == undefined )
303         return "undefined";
304     
305     if (!indent) 
306         indent = "";
307
308     switch ( typeof x ){
309         
310     case "string": {
311         var s = "\"";
312         for ( var i=0; i<x.length; i++ ){
313             if ( x[i] == '"' ){
314                 s += "\\\"";
315             }
316             else
317                 s += x[i];
318         }
319         return s + "\"";
320     }
321         
322     case "number": 
323     case "boolean":
324         return "" + x;
325             
326     case "object":{
327         var s = tojsonObject( x, indent , nolint , html);
328         if ( ( nolint == null || nolint == true ) && s.length < 80 && ( indent == null || indent.length == 0 ) ){
329             s = s.replace( /[\s\r\n ]+/gm , " " );
330         }
331         return s;
332     }
333         
334     case "function":
335         return x.toString();
336         
337
338     default:
339         throw "tojson can't handle type " + ( typeof x );
340     }
341     
342 }
343
344 tojsonObject = function( x, indent , nolint , html){
345     if(html) {
346       var lineEnding = "<br/>";
347       var tabSpace   = "&nbsp;";
348     }
349     else {
350       var lineEnding = nolint ? " " : "\n";
351       var tabSpace = nolint ? "" : "\t";
352     }
353
354     assert.eq( ( typeof x ) , "object" , "tojsonObject needs object, not [" + ( typeof x ) + "]" );
355
356     if (!indent)
357         indent = "";
358
359     if ( x.hasOwnProperty("__str__")) {
360         return x.__str__();
361     }
362
363     if ( typeof( x.tojson ) == "function" && x.tojson != tojson ) {
364         return x.tojson(indent,nolint,html);
365     }
366
367     if ( typeof( x.constructor.tojson ) == "function" && x.constructor.tojson != tojson ) {
368         return x.constructor.tojson( x, indent , nolint, html );
369     }
370
371     if ( x.toString() == "[object MaxKey]" )
372         return "{ $maxKey : 1 }";
373     if ( x.toString() == "[object MinKey]" )
374         return "{ $minKey : 1 }";
375
376     var s = "{" + lineEnding;
377
378     // push one level of indent
379     indent += tabSpace;
380
381     var total = 0;
382     for ( var k in x ) total++;
383     if ( total == 0 ) {
384         s += indent + lineEnding;
385     }
386
387     var keys = x;
388     if ( typeof( x._simpleKeys ) == "function" )
389         keys = x._simpleKeys();
390     var num = 1;
391     for ( var k in keys ){
392         var val = x[k];
393
394         s += indent + "\"" + k + "\" : " + tojson( val, indent , nolint );
395         if (num != total) {
396             s += ",";
397             num++;
398         }
399         s += lineEnding;
400     }
401
402     // pop one level of indent
403     indent = indent.substring(1);
404     return s + indent + "}";
405 }
406
407 shellPrint = function( x ){
408     it = x;
409     if ( x != undefined )
410         shellPrintHelper( x );
411 }
412
413 printjson = function(x){
414     print( tojson( x ) );
415 }
416
417 shellPrintHelper = function( x ){
418
419     if ( typeof( x ) == "undefined" ){
420
421         return;
422     }
423     
424     if ( x == null ){
425         print( "null" );
426         return;
427     }
428
429     if ( typeof x != "object" ) 
430         return print( x );
431     
432     var p = x.shellPrint;
433     if ( typeof p == "function" )
434         return x.shellPrint();
435
436     var p = x.tojson;
437     if ( typeof p == "function" )
438         print( x.tojson() );
439     else
440         print( tojson( x ) );
441 }
442
443 shellHelper = function( command , rest , shouldPrint ){
444     command = command.trim();
445     var args = rest.trim().replace(/;$/,"").split( "\s+" );
446     
447     if ( ! shellHelper[command] )
448         throw "no command [" + command + "]";
449     
450     var res = shellHelper[command].apply( null , args );
451     if ( shouldPrint ){
452         shellPrintHelper( res );
453     }
454     return res;
455 }
456
457 help = shellHelper.help = function(){
458     print( "HELP" );
459     print( "\t" + "show dbs                     show database names");
460     print( "\t" + "show collections             show collections in current database");
461     print( "\t" + "show users                   show users in current database");
462     print( "\t" + "show profile                 show most recent system.profile entries with time >= 1ms");
463     print( "\t" + "use <db name>                set curent database to <db name>" );
464     print( "\t" + "db.help()                    help on DB methods");
465     print( "\t" + "db.foo.help()                help on collection methods");
466     print( "\t" + "db.foo.find()                list objects in collection foo" );
467     print( "\t" + "db.foo.find( { a : 1 } )     list objects in foo where a == 1" );
468     print( "\t" + "it                           result of the last line evaluated; use to further iterate");
469 }
470
471 if ( typeof( Map ) == "undefined" ){
472     Map = function(){
473         this._data = {};
474     }
475 }
476
477 Map.hash = function( val ){
478     if ( ! val )
479         return val;
480
481     switch ( typeof( val ) ){
482     case 'string':
483     case 'number':
484     case 'date':
485         return val.toString();
486     case 'object':
487     case 'array':
488         var s = "";
489         for ( var k in val ){
490             s += k + val[k];
491         }
492         return s;
493     }
494
495     throw "can't hash : " + typeof( val );
496 }
497
498 Map.prototype.put = function( key , value ){
499     var o = this._get( key );
500     var old = o.value;
501     o.value = value;
502     return old;
503 }
504
505 Map.prototype.get = function( key ){
506     return this._get( key ).value;
507 }
508
509 Map.prototype._get = function( key ){
510     var h = Map.hash( key );
511     var a = this._data[h];
512     if ( ! a ){
513         a = [];
514         this._data[h] = a;
515     }
516     
517     for ( var i=0; i<a.length; i++ ){
518         if ( friendlyEqual( key , a[i].key ) ){
519             return a[i];
520         }
521     }
522     var o = { key : key , value : null };
523     a.push( o );
524     return o;
525 }
526
527 Map.prototype.values = function(){
528     var all = [];
529     for ( var k in this._data ){
530         this._data[k].forEach( function(z){ all.push( z.value ); } );
531     }
532     return all;
533 }
534
535 if ( typeof( gc ) == "undefined" ){
536     gc = function(){
537     }
538 }
539    
540
541 Math.sigFig = function( x , N ){
542     if ( ! N ){
543         N = 3;
544     }
545     var p = Math.pow( 10, N - Math.ceil( Math.log( Math.abs(x) ) / Math.log( 10 )) );
546     return Math.round(x*p)/p;
547 }
548