Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f601211
add ability to add query to dashboard from query page (re #154)
alison985 Aug 8, 2017
54637db
Add last_active_at column to users page (re #155)
alison985 Aug 12, 2017
ac4a36e
add partition key marker to Athena and Presto columns (re #185)
Dec 9, 2017
095092e
make autocomplete for large schemas faster (re #232)
Dec 9, 2017
7f5e470
Toggle for query editor autocomplete (re #282)
Dec 19, 2017
a3ae02e
hide query more menu if empty (re #208)
spasovski Aug 17, 2017
54d97ec
change pie chart colors (re #240)
alison985 Aug 18, 2017
9a8bbd5
Move events server side (re #245)
alison985 Sep 1, 2017
4c369f8
Run queries with no cached result in public dashboards (re #220)
Sep 6, 2017
0457c29
allow x-axis label truncation (re #249)
Jul 9, 2018
72298c5
secure cookies, add X-Content-Type-Options header (bug 1371613)
Sep 27, 2017
acf47d8
Merge mozilla schema updates with schema from master
Dec 12, 2017
0c0d990
merge upstream db changes
Feb 14, 2018
acf156d
Propagate query execution errors from Celery tasks properly (re #290)
Feb 27, 2018
cc3a37c
Support authentication for URL data source (re #330) (#336)
Mar 20, 2018
5e37e51
properly rollback failed db commits
Mar 21, 2018
c5acdf4
Install redash-stmo.
jezdez Feb 28, 2018
1483a4e
Extend the Remote User Auth backend with REMOTE_GROUPS ability (#311)
jezdez Mar 23, 2018
1b34c84
Unique names for query parameters (re #164)
Jan 16, 2018
5112831
Aggregate query results (re #35) (#339)
Mar 27, 2018
1c92d7e
Updates to docker-entrypoint for worker and scheduler (#364)
jasonthomas Apr 11, 2018
b9bd53b
Use new master / rc release release strategy
robotblake May 16, 2018
d56f75e
Closes #396: Integration with Flower.
May 11, 2018
aeaeab8
Closes #379: Add a task to monitor data source health.
Apr 27, 2018
f03e7b6
merge upstream db changes
Jun 28, 2018
42c191e
Set execute bit on alias script (#440)
jasonthomas Jul 11, 2018
44ac8b0
Update pyyaml from 3.12 to 3.13
pyup-bot Jul 30, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions bin/alias
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

set -eo pipefail

[ ! -z $DOCKERHUB_REPO ] && [ $# -eq 2 ]

VERSION="$1"
ALIAS="$2"

docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
docker tag $DOCKERHUB_REPO:$VERSION $DOCKERHUB_REPO:$ALIAS
docker push $DOCKERHUB_REPO:$ALIAS
10 changes: 8 additions & 2 deletions bin/docker-entrypoint
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ worker() {
/app/manage.py db upgrade
WORKERS_COUNT=${WORKERS_COUNT:-2}
QUEUES=${QUEUES:-queries,scheduled_queries,celery}
MAX_MEMORY=$(($(/usr/bin/awk '/MemTotal/ {print $2}' /proc/meminfo)/4))

echo "Starting $WORKERS_COUNT workers for queues: $QUEUES..."
exec /usr/local/bin/celery worker --app=redash.worker -c$WORKERS_COUNT -Q$QUEUES -linfo --maxtasksperchild=10 -Ofair
exec /usr/local/bin/celery worker --app=redash.worker -c$WORKERS_COUNT -Q$QUEUES -linfo \
--max-tasks-per-child=10 \
--max-memory-per-child=$MAX_MEMORY \
-Ofair
}

scheduler() {
Expand All @@ -17,7 +21,9 @@ scheduler() {

echo "Starting scheduler and $WORKERS_COUNT workers for queues: $QUEUES..."

exec /usr/local/bin/celery worker --app=redash.worker --beat -c$WORKERS_COUNT -Q$QUEUES -linfo --maxtasksperchild=10 -Ofair
exec /usr/local/bin/celery worker --app=redash.worker --beat -c$WORKERS_COUNT -Q$QUEUES -linfo \
--max-tasks-per-child=10 \
-Ofair
}

server() {
Expand Down
12 changes: 9 additions & 3 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,22 @@ test:
override:
- pytest --junitxml=$CIRCLE_TEST_REPORTS/junit.xml tests/
deployment:
latest:
master:
branch: master
owner: mozilla
commands:
- ./bin/deploy "latest"
hub_releases:
- ./bin/deploy "master"
release:
branch: release
owner: mozilla
commands:
- ./bin/deploy "rc"
milestone:
tag: /^m[0-9]+(\.[0-9]+)?$/
owner: mozilla
commands:
- ./bin/deploy "$CIRCLE_TAG"
- ./bin/alias "$CIRCLE_TAG" "latest"
general:
branches:
ignore:
Expand Down
2 changes: 0 additions & 2 deletions client/app/components/dashboards/widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,6 @@ function DashboardWidgetCtrl($location, $uibModal, $window, Events, currentUser)
return;
}

Events.record('delete', 'widget', this.widget.id);

this.widget.delete().then(() => {
if (this.deleted) {
this.deleted({});
Expand Down
2 changes: 1 addition & 1 deletion client/app/components/parameters.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ function ParametersDirective($location, $uibModal) {
}
scope.parameters.forEach((param) => {
if (param.value !== null || param.value !== '') {
$location.search(`p_${param.name}`, param.value);
$location.search(`p_${param.name}_${param.queryId}`, param.value);
}
});
}, true);
Expand Down
54 changes: 37 additions & 17 deletions client/app/components/queries/query-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,57 +80,77 @@ function queryEditor(QuerySnippet, $timeout) {
editor.getSession().setMode(newMode);
});

$scope.$watch('schema', (newSchema, oldSchema) => {
$scope.$watch('autoCompleteSchema', (newSchema, oldSchema) => {
if (newSchema !== oldSchema) {
if (newSchema === undefined) {
return;
}
const tokensCount = newSchema.reduce((totalLength, table) => totalLength + table.columns.length, 0);
// If there are too many tokens we disable live autocomplete,
// as it makes typing slower.
if (tokensCount > 5000) {
const tokensCount =
newSchema.reduce((totalLength, table) => totalLength + table.columns.length, 0);
// If there are too many tokens or if it's requested via the UI
// we disable live autocomplete, as it makes typing slower.
if (tokensCount > 5000 || !$scope.$parent.autocompleteQuery) {
editor.setOption('enableLiveAutocompletion', false);
editor.setOption('enableBasicAutocompletion', false);
} else {
editor.setOption('enableLiveAutocompletion', true);
editor.setOption('enableBasicAutocompletion', true);
}
}
});

$scope.$parent.$on('angular-resizable.resizing', () => {
editor.resize();
});
$scope.$parent.$watch('autocompleteQuery', () => {
editor.setOption('enableLiveAutocompletion', $scope.$parent.autocompleteQuery);
editor.setOption('enableBasicAutocompletion', $scope.$parent.autocompleteQuery);
});

editor.focus();
},
};

const schemaCompleter = {
getCompletions(state, session, pos, prefix, callback) {
if (prefix.length === 0 || !$scope.schema) {
// make a variable for the auto completion in the query editor
$scope.autoCompleteSchema = $scope.schema; // removeExtraSchemaInfo(

if (prefix.length === 0 || !$scope.autoCompleteSchema) {
callback(null, []);
return;
}

if (!$scope.schema.keywords) {
if (!$scope.autoCompleteSchema.keywords) {
const keywords = {};

$scope.schema.forEach((table) => {
$scope.autoCompleteSchema.forEach((table) => {
keywords[table.name] = 'Table';

table.columns.forEach((c) => {
keywords[c] = 'Column';
table.columns.forEach((c) => { // autoCompleteColumns
if (c.charAt(c.length - 1) === ')') {
let parensStartAt = c.indexOf('(') - 1;
c = c.substring(0, parensStartAt);
parensStartAt = 1; // linter complains without this line
}
// remove '[P] ' for partition keys
if (c.charAt(0) === '[') {
c = c.substring(4, c.length);
}
// keywords[c] = 'Column'; // dups columns
keywords[`${table.name}.${c}`] = 'Column';
});
});

$scope.schema.keywords = map(keywords, (v, k) => ({
name: k,
value: k,
score: 0,
meta: v,
}));
$scope.autoCompleteSchema.keywords = map(keywords, (v, k) =>
({
name: k,
value: k,
score: 0,
meta: v,
}));
}
callback(null, $scope.schema.keywords);
callback(null, $scope.autoCompleteSchema.keywords);
},
};

Expand Down
3 changes: 3 additions & 0 deletions client/app/components/queries/schedule-dialog.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@ <h4 class="modal-title">Refresh Schedule</h4>
Stop scheduling at date/time (format yyyy-MM-ddTHH:mm:ss, like 2016-12-28T14:57:00):
<schedule-until query="$ctrl.query" save-query="$ctrl.saveQuery"></schedule-until>
</label>
<label>
Number of query results to keep <schedule-keep-results query="$ctrl.query" save-query="$ctrl.saveQuery"></schedule-keep-results>
</label>
</div>
13 changes: 12 additions & 1 deletion client/app/components/queries/schedule-dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,21 @@ function scheduleUntil() {
};
}

function scheduleKeepResults() {
return {
restrict: 'E',
scope: {
query: '=',
saveQuery: '=',
},
template: '<input type="number" class="form-control" ng-model="query.schedule_resultset_size" ng-change="saveQuery()" ng-disabled="!query.schedule">',
};
}

const ScheduleForm = {
controller() {
this.query = this.resolve.query;
this.saveQuery = this.resolve.saveQuery;

if (this.query.hasDailySchedule()) {
this.refreshType = 'daily';
} else {
Expand All @@ -137,5 +147,6 @@ export default function init(ngModule) {
ngModule.directive('queryTimePicker', queryTimePicker);
ngModule.directive('queryRefreshSelect', queryRefreshSelect);
ngModule.directive('scheduleUntil', scheduleUntil);
ngModule.directive('scheduleKeepResults', scheduleKeepResults);
ngModule.component('scheduleDialog', ScheduleForm);
}
3 changes: 1 addition & 2 deletions client/app/pages/admin/outdated-queries/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import moment from 'moment';
import { Paginator } from '@/lib/pagination';
import template from './outdated-queries.html';

function OutdatedQueriesCtrl($scope, Events, $http, $timeout) {
Events.record('view', 'page', 'admin/outdated_queries');
function OutdatedQueriesCtrl($scope, $http, $timeout) {
$scope.autoUpdate = true;

this.queries = new Paginator([], { itemsPerPage: 50 });
Expand Down
3 changes: 1 addition & 2 deletions client/app/pages/admin/tasks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import moment from 'moment';
import { Paginator } from '@/lib/pagination';
import template from './tasks.html';

function TasksCtrl($scope, $location, $http, $timeout, Events) {
Events.record('view', 'page', 'admin/tasks');
function TasksCtrl($scope, $location, $http, $timeout) {
$scope.autoUpdate = true;

$scope.selectedTab = 'in_progress';
Expand Down
2 changes: 0 additions & 2 deletions client/app/pages/alert/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ function AlertCtrl($routeParams, $location, $sce, toastr, currentUser, Query, Ev

if (this.alertId === 'new') {
Events.record('view', 'page', 'alerts/new');
} else {
Events.record('view', 'alert', this.alertId);
}

this.trustAsHtml = html => $sce.trustAsHtml(html);
Expand Down
4 changes: 1 addition & 3 deletions client/app/pages/alerts-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ const stateClass = {
};

class AlertsListCtrl {
constructor(Events, Alert) {
Events.record('view', 'page', 'alerts');

constructor(Alert) {
this.showEmptyState = false;
this.showList = false;

Expand Down
2 changes: 0 additions & 2 deletions client/app/pages/dashboards/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@ function DashboardCtrl(
(dashboard) => {
this.dashboard = dashboard;
this.isDashboardOwner = currentUser.id === dashboard.user.id || currentUser.hasPermission('admin');
Events.record('view', 'dashboard', dashboard.id);
renderDashboard(dashboard, force);

if ($location.search().edit === true) {
Expand Down Expand Up @@ -229,7 +228,6 @@ function DashboardCtrl(

this.archiveDashboard = () => {
const archive = () => {
Events.record('archive', 'dashboard', this.dashboard.id);
this.dashboard.$delete();
};

Expand Down
4 changes: 1 addition & 3 deletions client/app/pages/data-sources/list.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import settingsMenu from '@/lib/settings-menu';
import template from './list.html';

function DataSourcesCtrl(Policy, Events, DataSource) {
Events.record('view', 'page', 'admin/data_sources');

function DataSourcesCtrl(Policy, DataSource) {
this.policy = Policy;
this.dataSources = DataSource.query();
}
Expand Down
9 changes: 1 addition & 8 deletions client/app/pages/data-sources/show.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ const logger = debug('redash:http');

function DataSourceCtrl(
$scope, $route, $routeParams, $http, $location, toastr,
currentUser, AlertDialog, Events, DataSource,
currentUser, AlertDialog, DataSource,
) {
Events.record('view', 'page', 'admin/data_source');

$scope.dataSource = $route.current.locals.dataSource;
$scope.dataSourceId = $routeParams.dataSourceId;
Expand Down Expand Up @@ -45,8 +44,6 @@ function DataSourceCtrl(

function deleteDataSource(callback) {
const doDelete = () => {
Events.record('delete', 'datasource', $scope.dataSource.id);

$scope.dataSource.$delete(() => {
toastr.success('Data source deleted successfully.');
$location.path('/data_sources/');
Expand All @@ -64,8 +61,6 @@ function DataSourceCtrl(
}

function testConnection(callback) {
Events.record('test', 'datasource', $scope.dataSource.id);

DataSource.test({ id: $scope.dataSource.id }, (httpResponse) => {
if (httpResponse.ok) {
toastr.success('Success');
Expand All @@ -81,8 +76,6 @@ function DataSourceCtrl(
}

function getDataSourceVersion(callback) {
Events.record('test', 'data_source_version', $scope.dataSource.id);

DataSource.version({ id: $scope.dataSource.id }, (httpResponse) => {
if (httpResponse.ok) {
const versionNumber = httpResponse.message;
Expand Down
4 changes: 1 addition & 3 deletions client/app/pages/destinations/list.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import settingsMenu from '@/lib/settings-menu';
import template from './list.html';

function DestinationsCtrl($scope, $location, toastr, currentUser, Events, Destination) {
Events.record('view', 'page', 'admin/destinations');

function DestinationsCtrl($scope, $location, toastr, currentUser, Destination) {
$scope.destinations = Destination.query();
}

Expand Down
5 changes: 1 addition & 4 deletions client/app/pages/destinations/show.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ const logger = debug('redash:http');

function DestinationCtrl(
$scope, $route, $routeParams, $http, $location, toastr,
currentUser, AlertDialog, Events, Destination,
currentUser, AlertDialog, Destination,
) {
Events.record('view', 'page', 'admin/destination');

$scope.destination = $route.current.locals.destination;
$scope.destinationId = $routeParams.destinationId;
Expand All @@ -34,8 +33,6 @@ function DestinationCtrl(

$scope.delete = () => {
const doDelete = () => {
Events.record('delete', 'destination', $scope.destination.id);

$scope.destination.$delete(() => {
toastr.success('Destination deleted successfully.');
$location.path('/destinations/');
Expand Down
3 changes: 1 addition & 2 deletions client/app/pages/groups/data-sources.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { includes } from 'lodash';
import template from './data-sources.html';

function GroupDataSourcesCtrl($scope, $routeParams, $http, Events, Group, DataSource) {
Events.record('view', 'group_data_sources', $scope.groupId);
function GroupDataSourcesCtrl($scope, $routeParams, $http, Group, DataSource) {
$scope.group = Group.get({ id: $routeParams.groupId });
$scope.dataSources = Group.dataSources({ id: $routeParams.groupId });
$scope.newDataSource = {};
Expand Down
3 changes: 1 addition & 2 deletions client/app/pages/groups/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import settingsMenu from '@/lib/settings-menu';
import { Paginator } from '@/lib/pagination';
import template from './list.html';

function GroupsCtrl($scope, $uibModal, currentUser, Events, Group) {
Events.record('view', 'page', 'groups');
function GroupsCtrl($scope, $uibModal, currentUser, Group) {
$scope.currentUser = currentUser;
$scope.groups = new Paginator([], { itemsPerPage: 20 });
Group.query((groups) => {
Expand Down
4 changes: 1 addition & 3 deletions client/app/pages/groups/show.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { includes } from 'lodash';
import template from './show.html';

function GroupCtrl($scope, $routeParams, $http, currentUser, Events, Group, User) {
Events.record('view', 'group', $scope.groupId);

function GroupCtrl($scope, $routeParams, $http, currentUser, Group, User) {
$scope.currentUser = currentUser;
$scope.group = Group.get({ id: $routeParams.groupId });
$scope.members = Group.members({ id: $routeParams.groupId });
Expand Down
3 changes: 0 additions & 3 deletions client/app/pages/queries-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ class QueriesListCtrl {
const page = parseInt($location.search().page || 1, 10);

this.term = $location.search().q;
if (isString(this.term) && this.term !== '') {
Events.record('search', 'query', '', { term: this.term });
}

this.defaultOptions = {};

Expand Down
Loading