]> git.sur5r.net Git - bacula/bacula/commitdiff
ebl Fill brestore cache when selecting a job
authorEric Bollengier <eric@eb.homelinux.org>
Sun, 30 Sep 2007 14:06:27 +0000 (14:06 +0000)
committerEric Bollengier <eric@eb.homelinux.org>
Sun, 30 Sep 2007 14:06:27 +0000 (14:06 +0000)
     Make drag&drop working between all elements
     Fix box size

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@5693 91ce42f0-d328-0410-95d8-f526ca767f89

gui/bweb/cgi/bresto.pl
gui/bweb/html/bresto.js

index a01e82877b27da8548e290fea72a60f5cf873b88..e8e355985ab3ab97d3f402567c8e0b1036e2c95d 100755 (executable)
@@ -121,6 +121,212 @@ sub set_limits
     $self->{offset} = $offset || 0;
 }
 
+sub update_cache
+{
+    my ($self) = @_;
+
+    $self->{dbh}->begin_work();
+
+    my $query = "
+  SELECT JobId from Job 
+   WHERE JobId NOT IN (SELECT JobId FROM brestore_knownjobid) AND JobStatus IN ('T', 'f', 'A') ORDER BY JobId";
+    my $jobs = $self->dbh_selectall_arrayref($query);
+
+    $self->update_brestore_table(map { $_->[0] } @$jobs);
+
+    print STDERR "Cleaning path visibility\n";
+    
+    my $nb = $self->dbh_do("
+  DELETE FROM brestore_pathvisibility
+      WHERE NOT EXISTS 
+   (SELECT 1 FROM Job WHERE JobId=brestore_pathvisibility.JobId)");
+
+    print STDERR "$nb rows affected\n";
+    print STDERR "Cleaning known jobid\n";
+
+    $nb = $self->dbh_do("
+  DELETE FROM brestore_knownjobid
+      WHERE NOT EXISTS 
+   (SELECT 1 FROM Job WHERE JobId=brestore_knownjobid.JobId)");
+
+    print STDERR "$nb rows affected\n";
+
+    $self->{dbh}->commit();
+}
+
+sub update_brestore_table
+{
+    my ($self, @jobs) = @_;
+
+    $self->debug(\@jobs);
+
+    foreach my $job (sort {$a <=> $b} @jobs)
+    {
+       my $query = "SELECT 1 FROM brestore_knownjobid WHERE JobId = $job";
+       my $retour = $self->dbh_selectrow_arrayref($query);
+       next if ($retour and ($retour->[0] == 1)); # We have allready done this one ...
+
+       print STDERR "Inserting path records for JobId $job\n";
+       $query = "INSERT INTO brestore_pathvisibility (PathId, JobId) 
+                   (SELECT DISTINCT PathId, JobId FROM File WHERE JobId = $job)";
+
+       $self->dbh_do($query);
+
+       # Now we have to do the directory recursion stuff to determine missing visibility
+       # We try to avoid recursion, to be as fast as possible
+       # We also only work on not allready hierarchised directories...
+
+       print STDERR "Creating missing recursion paths for $job\n";
+
+       $query = "SELECT brestore_pathvisibility.PathId, Path FROM brestore_pathvisibility 
+                 JOIN Path ON( brestore_pathvisibility.PathId = Path.PathId)
+                 LEFT JOIN brestore_pathhierarchy ON (brestore_pathvisibility.PathId = brestore_pathhierarchy.PathId)
+                 WHERE brestore_pathvisibility.JobId = $job
+                 AND brestore_pathhierarchy.PathId IS NULL
+                 ORDER BY Path";
+
+       my $sth = $self->dbh_prepare($query);
+       $sth->execute();
+       my $pathid; my $path;
+       $sth->bind_columns(\$pathid,\$path);
+       
+       while ($sth->fetch)
+       {
+           $self->build_path_hierarchy($path,$pathid);
+       }
+       $sth->finish();
+
+       # Great. We have calculated all dependancies. We can use them to add the missing pathids ...
+       # This query gives all parent pathids for a given jobid that aren't stored.
+       # It has to be called until no record is updated ...
+       $query = "
+       INSERT INTO brestore_pathvisibility (PathId, JobId) (
+       SELECT a.PathId,$job
+       FROM
+               (SELECT DISTINCT h.PPathId AS PathId
+               FROM brestore_pathhierarchy AS h
+               JOIN  brestore_pathvisibility AS p ON (h.PathId=p.PathId)
+               WHERE p.JobId=$job) AS a
+               LEFT JOIN
+               (SELECT PathId
+               FROM brestore_pathvisibility
+               WHERE JobId=$job) AS b
+               ON (a.PathId = b.PathId)
+       WHERE b.PathId IS NULL)";
+
+        my $rows_affected;
+       while (($rows_affected = $self->dbh_do($query)) and ($rows_affected !~ /^0/))
+       {
+           print STDERR "Recursively adding $rows_affected records from $job\n";
+       }
+       # Job's done
+       $query = "INSERT INTO brestore_knownjobid (JobId) VALUES ($job)";
+       $self->dbh_do($query);
+    }
+}
+
+sub parent_dir
+{
+    my ($path) = @_;
+    # Root Unix case :
+    if ($path eq '/')
+    {
+        return '';
+    }
+    # Root Windows case :
+    if ($path =~ /^[a-z]+:\/$/i)
+    {
+       return '';
+    }
+    # Split
+    my @tmp = split('/',$path);
+    # We remove the last ...
+    pop @tmp;
+    my $tmp = join ('/',@tmp) . '/';
+    return $tmp;
+}
+
+sub build_path_hierarchy
+{
+    my ($self, $path,$pathid)=@_;
+    # Does the ppathid exist for this ? we use a memory cache...
+    # In order to avoid the full loop, we consider that if a dir is allready in the
+    # brestore_pathhierarchy table, then there is no need to calculate all the hierarchy
+    while ($path ne '')
+    {
+       if (! $self->{cache_ppathid}->{$pathid})
+       {
+           my $query = "SELECT PPathId FROM brestore_pathhierarchy WHERE PathId = ?";
+           my $sth2 = $self->{dbh}->prepare_cached($query);
+           $sth2->execute($pathid);
+           # Do we have a result ?
+           if (my $refrow = $sth2->fetchrow_arrayref)
+           {
+               $self->{cache_ppathid}->{$pathid}=$refrow->[0];
+               $sth2->finish();
+               # This dir was in the db ...
+               # It means we can leave, the tree has allready been built for
+               # this dir
+               return 1;
+           } else {
+               $sth2->finish();
+               # We have to create the record ...
+               # What's the current p_path ?
+               my $ppath = parent_dir($path);
+               my $ppathid = $self->return_pathid_from_path($ppath);
+               $self->{cache_ppathid}->{$pathid}= $ppathid;
+               
+               $query = "INSERT INTO brestore_pathhierarchy (pathid, ppathid) VALUES (?,?)";
+               $sth2 = $self->{dbh}->prepare_cached($query);
+               $sth2->execute($pathid,$ppathid);
+               $sth2->finish();
+               $path = $ppath;
+               $pathid = $ppathid;
+           }
+       } else {
+          # It's allready in the cache.
+          # We can leave, no time to waste here, all the parent dirs have allready
+          # been done
+          return 1;
+       }
+    }
+    return 1;
+}
+
+sub return_pathid_from_path
+{
+    my ($self, $path) = @_;
+    my $query = "SELECT PathId FROM Path WHERE Path = ?";
+
+    #print STDERR $query,"\n" if $debug;
+    my $sth = $self->{dbh}->prepare_cached($query);
+    $sth->execute($path);
+    my $result =$sth->fetchrow_arrayref();
+    $sth->finish();
+    if (defined $result)
+    {
+       return $result->[0];
+
+    } else {
+        # A bit dirty : we insert into path, and we have to be sure
+        # we aren't deleted by a purge. We still need to insert into path to get
+        # the pathid, because of mysql
+        $query = "INSERT INTO Path (Path) VALUES (?)";
+        #print STDERR $query,"\n" if $debug;
+       $sth = $self->{dbh}->prepare_cached($query);
+       $sth->execute($path);
+       $sth->finish();
+        
+       $query = "SELECT PathId FROM Path WHERE Path = ?";
+       #print STDERR $query,"\n" if $debug;
+       $sth = $self->{dbh}->prepare_cached($query);
+       $sth->execute($path);
+       $result = $sth->fetchrow_arrayref();
+       $sth->finish();
+       return $result->[0];
+    }
+}
+
 sub ls_files
 {
     my ($self) = @_;
@@ -295,6 +501,12 @@ sub set_job_ids_for_date
     return @CurrentJobIds;
 }
 
+sub dbh_selectrow_arrayref
+{
+    my ($self, $query) = @_;
+    $self->debug($query, up => 1);
+    return $self->{dbh}->selectrow_arrayref($query);
+}
 
 # Returns list of versions of a file that could be restored
 # returns an array of 
@@ -524,6 +736,8 @@ print join(",", $args->{qdate}, $args->{client}, @jobid), "\n";
 }
 
 $bvfs->set_curjobids(@jobid);
+
+
 $bvfs->set_limits($args->{limit}, $args->{offset});
 
 print CGI::header('application/x-javascript');
@@ -560,6 +774,10 @@ if ($action eq 'list_client') {
     print "]\n";
 }
 
+if (CGI::param('init')) {
+    $bvfs->update_brestore_table(@jobid);
+}
+
 my $pathid = CGI::param('node') || '';
 my $path = CGI::param('path');
 
index 2281ebe638d38df5900c62bf8939a2d3575bd59d..493689d252b338237ebd649c905365468998910f 100644 (file)
@@ -48,6 +48,25 @@ Ext.namespace('Ext.brestore');
 
 Ext.brestore.jobid=0;
 Ext.brestore.client='';
+Ext.brestore.path='';
+Ext.brestore.root_path='';
+
+
+function get_node_path(node)
+{
+   var temp='';
+   for (var p = node; p; p = p.parentNode) {
+       if (p.parentNode) {
+          if (p.text == '/') {
+             temp = p.text + temp;
+          } else {
+          temp = p.text + '/' + temp;
+          }
+       }
+   }
+   return Ext.brestore.root_path + temp;
+}
+
 
 function ext_init()
 {
@@ -68,7 +87,7 @@ function ext_init()
 
     // set the root node
     var root = new Ext.tree.AsyncTreeNode({
-        text: 'Root',
+        text: 'Select a job',
         draggable:false,
         id:'source'
     });
@@ -78,11 +97,13 @@ function ext_init()
     tree.render();
 //    root.expand();
 
-    tree.on('click', function(e) { 
+    tree.on('click', function(node, event) { 
+        Ext.brestore.path = get_node_path(node);
+
         file_store.removeAll();
         file_store.load({params:{action: 'list_files',
                                  jobid:Ext.brestore.jobid, 
-                                 node:e.id}
+                                 node:node.id}
                        });
         return true;
     });
@@ -117,7 +138,7 @@ function ext_init()
            id:        'name', // id assigned so we can apply custom css (e.g. .x-grid-col-topic b { color:#333 })
            header:    'File',
            dataIndex: 'name',
-           width:     250,
+           width:     100,
            css:       'white-space:normal;'
         },{
            header:    "Size",
@@ -127,7 +148,7 @@ function ext_init()
         },{
            header:    "Date",
            dataIndex: 'mtime',
-           width:     50
+           width:     100
         },{
            dataIndex: 'pathid',
            hidden: true
@@ -163,6 +184,7 @@ function ext_init()
         return true;
     });
 
+    // TODO: selection only when using dblclick
     files_grid.selModel.on('rowselect', function(e,i,r) { 
         Ext.brestore.filename = r.json[3];
         file_versions_store.load({params:{action: 'list_versions',
@@ -186,6 +208,7 @@ function ext_init()
    {name: 'fileid'    },
    {name: 'filenameid'},
    {name: 'pathid'    },
+   {name: 'name'      },
    {name: 'size',     type: 'int'  },
    {name: 'mtime',    type: 'date', dateFormat: 'Y-m-d h:i:s'}
         ]))
@@ -193,10 +216,12 @@ function ext_init()
 
    var file_selection_cm = new Ext.grid.ColumnModel([{
            id:        'name', // id assigned so we can apply custom css (e.g. .x-grid-col-topic b { color:#333 })
+           header:    "Name",
            dataIndex: 'name',
-           hidden: true
+           width:     250
         },{
            header:    "JobId",
+           width:     50,
            dataIndex: 'jobid'
         },{
            header:    "Size",
@@ -206,7 +231,7 @@ function ext_init()
         },{
            header:    "Date",
            dataIndex: 'mtime',
-           width:     50
+           width:     100
         },{
            dataIndex: 'pathid',
            hidden: true
@@ -248,35 +273,63 @@ function ext_init()
         ddGroup : 'TreeDD',
         copy:false,
         notifyDrop : function(dd, e, data){
-//             if (data.selections) {
-//                     alert("grid");
-//             }
-//
-//             if (data.node) {
-//                     alert("tree");
-//             }
-//
-               file_selection_store.add(
-                 new file_selection_record({
-                       jobid:1,
-                       fileid:1,
-                       filenameid:1,
-                       pathid:1,
-                       size:1,
-                       mtime:'2007-01-01 01:00:00'
-                })
-               );
-
-               return true;
-//              var sm=grid.getSelectionModel();
-//              var rows=sm.getSelections();
-//              var cindex=dd.getDragData(e).rowIndex;
-//              for(i = 0; i < rows.length; i++) {
-//                      rowData=ds.getById(rows[i].id);
-//                      if(!this.copy) 
-//                              ds.remove(ds.getById(rows[i].id));
-//                      ds.insert(cindex,rowData);
-//              };
+           var r;
+           //TODO: gerer la multi-selection
+           if (data.selections) {
+             if (data.grid.id == 'div-files') {
+                 for(var i=0;i<data.selections.length;i++) {
+                    r = new file_selection_record({
+                      jobid:     Ext.brestore.jobid,
+                      fileid:    data.selections[i].json[0],
+                      filenameid:data.selections[i].json[1],
+                      pathid:    data.selections[i].json[2],
+                      name: Ext.brestore.path + data.selections[i].json[3],
+                      size:      data.selections[i].json[4],
+                      mtime:     data.selections[i].json[5]
+                    });
+                    file_selection_store.add(r)
+                 }
+             }
+
+             if (data.grid.id == 'div-file-versions') {
+                    r = new file_selection_record({
+                      jobid:     data.selections[0].json[3],
+                      fileid:    data.selections[0].json[0],
+                      filenameid:data.selections[0].json[1],
+                      pathid:    data.selections[0].json[2],
+                      name: Ext.brestore.path + Ext.brestore.filename,
+                      size:      data.selections[0].json[7],
+                      mtime:     data.selections[0].json[8]     
+                    });
+                    file_selection_store.add(r)
+             }
+           }
+  
+           if (data.node) {
+              var path= get_node_path(data.node);
+              r = new file_selection_record({
+                      jobid:     Ext.brestore.jobid,
+                      fileid:    0,
+                      filenameid:0,
+                      pathid:    data.node.id,
+                      name:      path,
+                      size:      4096,
+                      mtime:     0
+              });
+              file_selection_store.add(r)
+           }
+  
+           return true;
+
+//         var sm=grid.getSelectionModel();
+//         var rows=sm.getSelections();
+//         var cindex=dd.getDragData(e).rowIndex;
+//         for(i = 0; i < rows.length; i++) {
+//                 rowData=ds.getById(rows[i].id);
+//                 if(!this.copy) 
+//                         ds.remove(ds.getById(rows[i].id));
+//                 ds.insert(cindex,rowData);
+//         };
         }
     });
 
@@ -319,12 +372,14 @@ function ext_init()
         },{
            header:    "InChanger",
            dataIndex: 'inchanger',
+           width:     60,
            renderer:  rd_vol_is_online
         },{
            header:    "Volume",
            dataIndex: 'volume'
         },{
            header:    "JobId",
+           width:     50,
            dataIndex: 'jobid'
         },{
            header:    "Size",
@@ -334,11 +389,11 @@ function ext_init()
         },{
            header:    "Date",
            dataIndex: 'mtime',
-           width:     50
+           width:     100
         },{
            header:    "MD5",
            dataIndex: 'md5',
-           width:     50
+           width:     160
         },{
            dataIndex: 'pathid',
            hidden: true
@@ -441,8 +496,10 @@ function ext_init()
     job_combo.on('select', function(e,c) {
         // TODO: choose between date and jobid here (with a toolbar bp ?)
         Ext.brestore.jobid = c.json[0];
+        Ext.brestore.root_path='';
         root.setText("Root");
         tree_loader.baseParams = { action:'list_dirs',
+                                   init:1,
                                    jobid:Ext.brestore.jobid };
         root.reload();
     });
@@ -498,6 +555,7 @@ function ext_init()
           cls:'x-btn-text-icon',
           handler: function() { 
                 var where = where_field.getValue();
+                Ext.brestore.root_path=where;
                 root.setText(where);
                 tree_loader.baseParams = { action:'list_dirs',
                                            jobid:Ext.brestore.jobid,
@@ -518,13 +576,13 @@ function ext_init()
             split: true, initialSize: 300
         },
         east: {
-            split: true, initialSize: 500
+            split: true, initialSize: 550
         },
         west: {
             split: true, initialSize: 300
         },
         center: {
-            initialSize: 600
+            initialSize: 450
         }        
         
     });