[Groonga-commit] groonga/groonga-admin at 9181451 [master] Make schema loader service

Back to archive index

Kouhei Sutou null+****@clear*****
Sun Dec 21 16:28:18 JST 2014


Kouhei Sutou	2014-12-21 16:28:18 +0900 (Sun, 21 Dec 2014)

  New Revision: 9181451d3e50ca5c82cdd3e987afd51a98071503
  https://github.com/groonga/groonga-admin/commit/9181451d3e50ca5c82cdd3e987afd51a98071503

  Message:
    Make schema loader service

  Added files:
    app/scripts/services/schema-loader.js
  Modified files:
    app/index.html
    app/scripts/controllers/table-search-controller.js
    app/scripts/controllers/top-controller.js
    app/scripts/groonga-client.js
    app/views/tables/search.html

  Modified: app/index.html (+1 -0)
===================================================================
--- app/index.html    2014-12-16 22:10:02 +0900 (d974221)
+++ app/index.html    2014-12-21 16:28:18 +0900 (ac16093)
@@ -81,6 +81,7 @@
         <script src="scripts/groonga-client/response/table-list.js"></script>
         <script src="scripts/groonga-client/response/column-list.js"></script>
         <script src="scripts/app.js"></script>
+        <script src="scripts/services/schema-loader.js"></script>
         <script src="scripts/controllers/top-controller.js"></script>
         <script src="scripts/controllers/table-search-controller.js"></script>
         <!-- endbuild -->

  Modified: app/scripts/controllers/table-search-controller.js (+66 -148)
===================================================================
--- app/scripts/controllers/table-search-controller.js    2014-12-16 22:10:02 +0900 (17f6f30)
+++ app/scripts/controllers/table-search-controller.js    2014-12-21 16:28:18 +0900 (633abb1)
@@ -9,8 +9,9 @@
  */
 angular.module('groongaAdminApp')
   .controller('TableSearchController', [
-    '$scope', '$routeParams', '$location', '$q', '$http', '$filter',
-    function ($scope, $routeParams, $location, $q, $http, $filter) {
+    '$scope', '$routeParams', '$location', '$http', '$filter', 'schemaLoader',
+    function ($scope, $routeParams, $location, $http, $filter, schemaLoader) {
+      var schema;
       var client = new GroongaClient($http);
 
       function findElement(array, finder) {
@@ -30,7 +31,12 @@ angular.module('groongaAdminApp')
       }
 
       function initialize() {
-        $scope.table = $routeParams.table;
+        $scope.table = {
+          name: $routeParams.table,
+          allColumns: [],
+          timeColumns: [],
+          indexedColumns: []
+        };
         $scope.style = 'table';
         $scope.response = {
           rawData: [],
@@ -40,10 +46,6 @@ angular.module('groongaAdminApp')
           elapsedTimeInMilliseconds: 0,
           nTotalRecords: 0
         };
-        $scope.allTables = [];
-        $scope.allColumns = [];
-        $scope.timeColumns = [];
-        $scope.indexedColumns = [];
         $scope.commandLine = '';
         $scope.message = '';
         $scope.parameters = angular.copy($location.search());
@@ -69,6 +71,13 @@ angular.module('groongaAdminApp')
         return names.join(',');
       }
 
+      function packMatchColumns(columns) {
+        var names = columns.map(function(column) {
+          return column.indexName;
+        });
+        return names.join(',');
+      }
+
       function packSortColumns(columns) {
         var keys = columns.map(function(column) {
           if (column.sort === 'ascending') {
@@ -105,7 +114,7 @@ angular.module('groongaAdminApp')
       }
 
       function buildFilter() {
-        var timeQueries = $scope.timeColumns.filter(function(column) {
+        var timeQueries = $scope.table.timeColumns.filter(function(column) {
           return column.start || column.end;
         }).map(function(column) {
           var operator;
@@ -141,12 +150,12 @@ angular.module('groongaAdminApp')
       function buildParameters() {
         var parameters = angular.copy($scope.parameters);
 
-        var matchColumns = $scope.indexedColumns.filter(function(column) {
+        var matchColumns = $scope.table.indexedColumns.filter(function(column) {
           return column.inUse;
         });
-        parameters.match_columns = packColumns(matchColumns);
+        parameters.match_columns = packMatchColumns(matchColumns);
 
-        var outputColumns = $scope.allColumns.filter(function(column) {
+        var outputColumns = $scope.table.allColumns.filter(function(column) {
           return column.output;
         });
         parameters.output_columns = packColumns(outputColumns);
@@ -154,12 +163,12 @@ angular.module('groongaAdminApp')
         parameters.offset = ($scope.currentPage - 1) * $scope.nRecordsInPage;
         parameters.limit = $scope.nRecordsInPage;
 
-        var sortColumns = $scope.allColumns.filter(function(column) {
+        var sortColumns = $scope.table.allColumns.filter(function(column) {
           return column.sort;
         });
         parameters.sortby = packSortColumns(sortColumns);
 
-        var drilldowns = $scope.allColumns.filter(function(column) {
+        var drilldowns = $scope.table.allColumns.filter(function(column) {
           return column.drilldown;
         });
         parameters.drilldown = packColumns(drilldowns);
@@ -198,7 +207,7 @@ angular.module('groongaAdminApp')
       }
 
       function toggleSort(column) {
-        var columnInfo = findElement($scope.allColumns, function(columnInfo) {
+        var columnInfo = findElement($scope.table.allColumns, function(columnInfo) {
           return columnInfo.name === column.name;
         });
         if (!columnInfo) {
@@ -222,30 +231,13 @@ angular.module('groongaAdminApp')
         incrementalSearch();
       }
 
-      function isTableType(type) {
-        return $scope.allTables.some(function(table) {
-          return table.name === type;
-        });
-      }
-
-      function isTextType(type) {
-        switch (type) {
-        case 'ShortText':
-        case 'Text':
-        case 'LongText':
-          return true;
-        default:
-          return false;
-        }
-      }
-
       function selectDrilldown(key, value) {
         var queryKey = key;
-        var column = findElement($scope.allColumns, function(column) {
+        var column = findElement($scope.table.allColumns, function(column) {
           return column.name === key;
         });
         if (column) {
-          if (isTableType(column.type)) {
+          if (column.isTableType) {
             queryKey += '._key';
           }
         }
@@ -302,12 +294,16 @@ angular.module('groongaAdminApp')
           type: column.range,
           output: output,
           drilldown: drilldown,
-          sort: sort
+          sort: sort,
+          indexes: column.indexes || [],
+          isTextType: column.isTextType,
+          isTableType: column.isTableType
         };
       }
 
       function addColumn(columnInfo) {
-        $scope.allColumns.push(columnInfo);
+        $scope.table.allColumns.push(columnInfo);
+
         if (columnInfo.type === 'Time') {
           var timeColumnInfo = {
             name: columnInfo.name,
@@ -316,8 +312,23 @@ angular.module('groongaAdminApp')
             end: null,
             endIncluded: true
           };
-          $scope.timeColumns.push(timeColumnInfo);
+          $scope.table.timeColumns.push(timeColumnInfo);
         }
+
+        var matchColumns = $scope.parameters.match_columns;
+        columnInfo.indexes.forEach(function(/* index */) {
+          var indexName = columnInfo.name;
+          var inUse = true;
+          if (matchColumns) {
+            inUse = (matchColumns.indexOf(indexName) !== -1);
+          }
+          var indexedColumnInfo = {
+            name: columnInfo.name,
+            indexName: indexName,
+            inUse: inUse
+          };
+          $scope.table.indexedColumns.push(indexedColumnInfo);
+        });
       }
 
       function applyTimeQueries() {
@@ -350,7 +361,7 @@ angular.module('groongaAdminApp')
             var startBorder = parts[3];
             var end = parts[4];
             var endBorder = parts[5];
-            timeColumn = findElement($scope.timeColumns, function(column) {
+            timeColumn = findElement($scope.table.timeColumns, function(column) {
               return column.name === columnName;
             });
             if (!timeColumn) {
@@ -365,7 +376,7 @@ angular.module('groongaAdminApp')
             columnName = parts[0];
             operator = parts[1];
             time = parts[2];
-            timeColumn = findElement($scope.timeColumns, function(column) {
+            timeColumn = findElement($scope.table.timeColumns, function(column) {
               return column.name === columnName;
             });
             if (!timeColumn) {
@@ -393,116 +404,9 @@ angular.module('groongaAdminApp')
         });
       }
 
-      function extractColumnsInfo(table, columns) {
-        columns.forEach(function(column) {
-          if (!column.isIndex) {
-            return;
-          }
-          if (column.range !== $scope.table) {
-            return;
-          }
-          var matchColumns = $scope.parameters.match_columns;
-          column.sources.forEach(function(source) {
-            var localName;
-            if (source.indexOf('.') === -1) {
-              localName = '_key';
-            } else {
-              localName = source.split('.')[1];
-            }
-
-            var indexName = localName;
-            var sourceColumn = findElement($scope.allColumns, function(column) {
-              return column.name === localName;
-            });
-            if (sourceColumn) {
-              var targetType = sourceColumn.type;
-              var isTableTypeSource = isTableType(targetType);
-              if (isTableTypeSource) {
-                var table = findElement($scope.allTables, function(table) {
-                  return table.name === targetType;
-                });
-                targetType = table.domain;
-              }
-              if (!isTextType(targetType)) {
-                return;
-              }
-
-              if (isTableTypeSource) {
-                indexName += '._key';
-              }
-            }
-
-            var inUse = true;
-            if (matchColumns) {
-              inUse = matchColumns.indexOf(indexName) !== -1;
-            }
-
-            $scope.indexedColumns.push({
-              name: indexName,
-              label: localName,
-              inUse: inUse
-            });
-          });
-        });
-      }
-
-      function extractTableInfo(table) {
-        return client.execute('column_list', {table: table.name})
-          .success(function(response) {
-            extractColumnsInfo(table, response.columns());
-          });
-      }
-
-      function fillOptions() {
-        client.execute('table_list')
-          .success(function(response) {
-            $scope.allTables = response.tables();
-
-            var idColumn = {
-              name: '_id',
-              range: 'UInt32'
-            };
-            addColumn(createColumnInfo(idColumn));
-
-            client.execute('column_list', {table: $scope.table})
-              .success(function(response) {
-                var columns = response.columns();
-
-                columns.forEach(function(column) {
-                  if (column.isIndex) {
-                    return;
-                  }
-                  addColumn(createColumnInfo(column));
-                });
-                applyTimeQueries();
-
-                var currentTable = findElement($scope.allTables, function(table) {
-                  return table.name === $scope.table;
-                });
-                extractColumnsInfo(currentTable, columns);
-
-                var tasks = [];
-                $scope.allTables.forEach(function(table) {
-                  if (table.name === $scope.table) {
-                    return;
-                  }
-                  tasks.push(extractTableInfo(table));
-                });
-                $q.all(tasks)
-                  .then(function() {
-                    var parameters = buildParameters();
-                    if ($scope.parameters.offset) {
-                      parameters.offset = $scope.parameters.offset;
-                    }
-                    select(parameters);
-                  });
-              });
-          });
-      }
-
       function select(userParameters) {
         var parameters = {
-          table: $scope.table
+          table: $scope.table.name
         };
         angular.forEach(userParameters, function(value, key) {
           if (key in parameters) {
@@ -527,7 +431,7 @@ angular.module('groongaAdminApp')
           $scope.response.nTotalRecords = response.nTotalRecords();
           $scope.response.columns = response.columns();
           $scope.response.columns.forEach(function(column) {
-            var columnInfo = findElement($scope.allColumns, function(columnInfo) {
+            var columnInfo = findElement($scope.table.allColumns, function(columnInfo) {
               return columnInfo.name === column.name;
             });
             if (columnInfo) {
@@ -564,5 +468,19 @@ angular.module('groongaAdminApp')
       }
 
       initialize();
-      fillOptions();
+      schemaLoader()
+        .then(function(_schema) {
+          schema = _schema;
+          var table = schema.tables[$scope.table.name];
+          angular.forEach(table.columns, function(column) {
+            addColumn(createColumnInfo(column));
+          });
+          applyTimeQueries();
+
+          var parameters = buildParameters();
+          if ($scope.parameters.offset) {
+            parameters.offset = $scope.parameters.offset;
+          }
+          select(parameters);
+        });
     }]);

  Modified: app/scripts/controllers/top-controller.js (+11 -8)
===================================================================
--- app/scripts/controllers/top-controller.js    2014-12-16 22:10:02 +0900 (46fd18a)
+++ app/scripts/controllers/top-controller.js    2014-12-21 16:28:18 +0900 (ca81f47)
@@ -8,11 +8,14 @@
  * Controller of the groongaAdminApp
  */
 angular.module('groongaAdminApp')
-  .controller('TopController', function ($scope, $http) {
-    $scope.tables = [];
-    var client = new GroongaClient($http);
-    var request = client.execute('table_list', {});
-    request.success(function(response) {
-      $scope.tables = response.tables();
-    });
-  });
+  .controller('TopController', [
+    '$scope', 'schemaLoader',
+    function ($scope, schemaLoader) {
+      $scope.tables = [];
+      schemaLoader()
+        .then(function(schema) {
+          angular.forEach(schema.tables, function(table) {
+            $scope.tables.push(table);
+          });
+        });
+    }]);

  Modified: app/scripts/groonga-client.js (+8 -4)
===================================================================
--- app/scripts/groonga-client.js    2014-12-16 22:10:02 +0900 (ef6ec0e)
+++ app/scripts/groonga-client.js    2014-12-21 16:28:18 +0900 (78e2c57)
@@ -32,15 +32,19 @@
 
   GroongaClient.Request.prototype.success = function(callback) {
     var name = this._name;
-    return this._rawRequest.success(function(data, status, headers, config) {
+    return this._rawRequest.then(function(rawResponse) {
       var ResponseConstructor = GroongaClient.Response.find(name);
-      var response = new ResponseConstructor(data);
-      callback(response, status, headers, config);
+      var response = new ResponseConstructor(rawResponse.data);
+      return callback(response, rawResponse);
     });
   };
 
   GroongaClient.Request.prototype.error = function(callback) {
-    return this._rawRequest.error(callback);
+    return this._rawRequest.then(null, function(rawResponse) {
+      var ResponseConstructor = GroongaClient.Response.find(name);
+      var response = new ResponseConstructor(rawResponse.data);
+      return callback(response, rawResponse);
+    });
   };
 
   GroongaClient.Request.prototype.commandLine = function() {

  Added: app/scripts/services/schema-loader.js (+141 -0) 100644
===================================================================
--- /dev/null
+++ app/scripts/services/schema-loader.js    2014-12-21 16:28:18 +0900 (3581d06)
@@ -0,0 +1,141 @@
+'use strict';
+
+/**
+ * @ngdoc function
+ * @name groongaAdminApp.service:schemaLoader
+ * @description
+ * # schemaLoader
+ * Groonga database schema loader.
+ */
+angular.module('groongaAdminApp')
+  .factory('schemaLoader', [
+    '$q', '$http', '$timeout',
+    function ($q, $http, $timeout) {
+      var fetching = false;
+      var waitingDeferes = [];
+      var fetched = false;
+      var schema = {
+        tables: {}
+      };
+      var client = new GroongaClient($http);
+
+      function isTextType(typeName) {
+        switch (typeName) {
+        case 'ShortText':
+        case 'Text':
+        case 'LongText':
+          return true;
+        default:
+          return false;
+        }
+      }
+
+      function isReferenceType(typeName) {
+        return typeName in schema.tables;
+      }
+
+      function resolveColumn(column) {
+        column.isTextType = isTextType(column.range);
+        column.isReferenceType = isReferenceType(column.range);
+      }
+
+      function resolveColumns() {
+        angular.forEach(schema.tables, function(table) {
+          angular.forEach(table.columns, function(column) {
+            resolveColumn(column);
+          });
+        });
+      }
+
+      function resolveIndex(column) {
+        var table = schema.tables[column.range];
+        column.sources.forEach(function(source) {
+          var columnName;
+          if (source.indexOf('.') === -1) {
+            columnName = '_key';
+          } else {
+            columnName = source.split('.')[1];
+          }
+          var targetColumn = table.columns[columnName];
+          targetColumn.indexes.push(column);
+        });
+      }
+
+      function resolveIndexes() {
+        angular.forEach(schema.tables, function(table) {
+          angular.forEach(table.columns, function(column) {
+            if (column.isIndex) {
+              resolveIndex(column);
+            }
+          });
+        });
+      }
+
+      function addColumn(table, column) {
+        column.table = table;
+        column.indexes = [];
+        table.columns[column.name] = column;
+      }
+
+      function fetchColumns(table) {
+        table.columns = {};
+
+        addColumn(table, {
+          name: '_id',
+          range: 'UInt32'
+        });
+
+        return client.execute('column_list', {table: table.name})
+          .success(function(response) {
+            var columns = response.columns();
+
+            columns.forEach(function(column) {
+              addColumn(table, column);
+            });
+          });
+      }
+
+      function fetchTables() {
+        return client.execute('table_list')
+          .success(function(response) {
+            response.tables().forEach(function(table) {
+              schema.tables[table.name] = table;
+            });
+
+            var fetchColumnsTasks = [];
+            angular.forEach(schema.tables, function(table) {
+              fetchColumnsTasks.push(fetchColumns(table));
+            });
+
+            return $q.all(fetchColumnsTasks)
+              .then(function() {
+                resolveColumns();
+                resolveIndexes();
+                fetched = true;
+                fetching = false;
+                waitingDeferes.forEach(function(defer) {
+                  defer.resolve(schema);
+                });
+                waitingDeferes = [];
+                return schema;
+              });
+          });
+      }
+
+      return function() {
+        if (fetching) {
+          var defer = $q.defer();
+          waitingDeferes.push(defer);
+          return defer.promise;
+        } else if (fetched) {
+          var defer = $q.defer();
+          $timeout(function() {
+            defer.resolve(schema);
+          });
+          return defer.promise;
+        } else {
+          fetching = true
+          return fetchTables();
+        }
+      };
+    }]);

  Modified: app/views/tables/search.html (+5 -5)
===================================================================
--- app/views/tables/search.html    2014-12-16 22:10:02 +0900 (bba6ee5)
+++ app/views/tables/search.html    2014-12-21 16:28:18 +0900 (0c7cdc7)
@@ -2,7 +2,7 @@
   <ol class="breadcrumb">
     <li><a href="#">Top</a></li>
     <li><a href="#/tables/">Tables</a></li>
-    <li><a href="#/tables/{{table}}">{{table}}</a></li>
+    <li><a href="#/tables/{{table.name}}">{{table.name}}</a></li>
     <li class="active">Search</li>
   </ol>
 
@@ -44,7 +44,7 @@
               </tr>
             </thead>
             <tbody>
-              <tr ng-repeat="column in allColumns track by $index">
+              <tr ng-repeat="column in table.allColumns track by $index">
                 <td>{{column.name}}</td>
                 <td><input type="checkbox"
                            ng-model="column.output"
@@ -87,12 +87,12 @@
     <form class="search-form" role="search">
       <div class="form-group">
         <div class="input-group">
-          <span ng-repeat="indexedColumn in indexedColumns track by $index">
+          <span ng-repeat="indexedColumn in table.indexedColumns track by $index">
             <label>
               <input type="checkbox"
                      ng-model="indexedColumn.inUse"
                      ng-change="incrementalSearch()">
-              {{indexedColumn.label}}
+              {{indexedColumn.name}}
             </label>
           </span>
         </div>
@@ -107,7 +107,7 @@
         </div>
       </div>
       <div class="form-group time-query"
-           ng-repeat="timeColumn in timeColumns track by $index">
+           ng-repeat="timeColumn in table.timeColumns track by $index">
         {{timeColumn.name}}:
         <div class="dropdown">
           <div class="input-group">
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index