Skip to content

Commit

Permalink
Merge pull request #351 from devinit/fix/published-datasets
Browse files Browse the repository at this point in the history
Fix | published datasets
  • Loading branch information
edwinmp committed Oct 8, 2020
2 parents 958b593 + 6ea0397 commit d29cfd9
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 73 deletions.
36 changes: 0 additions & 36 deletions core/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ def create(self, validated_data):
operation.operation_query = query.build_query(operation=operation)
operation.count_rows = True
operation.save()
self.create_operation_data_aliases(operation)

return operation

Expand Down Expand Up @@ -220,44 +219,9 @@ def update(self, instance, validated_data):
instance.operation_query = query.build_query(operation=instance)
instance.count_rows = True
instance.save()
self.update_operation_data_aliases(instance)

return instance

def create_operation_data_aliases(self, operation):
count, data = query.query_table(operation, 1, 0, estimate_count=True)
try:
data_column_keys = data[0].keys()
first_step = operation.get_operation_steps()[0]
columns = SourceColumnMap.objects.filter(source=first_step.source, name__in=data_column_keys)
for column in data_column_keys:
matching = columns.filter(name=column).first()
alias = self.create_operation_alias(operation, column, matching.alias if matching else column)
alias.save()
except: # FIXME: handle specific errors
pass

def update_operation_data_aliases(self, operation):
count, data = query.query_table(operation, 1, 0, estimate_count=True)
try:
data_column_keys = data[0].keys()
first_step = operation.get_operation_steps()[0]
columns = SourceColumnMap.objects.filter(source=first_step.source, name__in=data_column_keys)
# delete obsolete aliases
OperationDataColumnAlias.objects.filter(operation=operation).exclude(column_name__in=data_column_keys).delete()
for column in data_column_keys:
existing_alias = OperationDataColumnAlias.objects.filter(operation=operation, column_name=column).first()
if not existing_alias:
matching = columns.filter(name=column).first()
alias = self.create_operation_alias(operation, column, matching.alias if matching else column)
alias.save()
except: # FIXME: handle specific errors
pass

def create_operation_alias(self, operation, column_name, column_alias):
return OperationDataColumnAlias.objects.create(
operation=operation, column_name=column_name, column_alias=column_alias)


class ThemeSerializer(serializers.ModelSerializer):
user = serializers.ReadOnlyField(source='user.username')
Expand Down
33 changes: 32 additions & 1 deletion core/tasks.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from ddw_analyst_ui.celery import app

from core import query
from core.pypika_utils import QueryBuilder
from data.db_manager import count_rows
from core.models import Operation
from core.models import Operation, OperationDataColumnAlias, SourceColumnMap

@app.task(bind=False)
def count_operation_rows(id):
Expand All @@ -16,3 +17,33 @@ def count_operation_rows(id):
return { "status": "success" }
else:
return { "status": "failed" }


def create_operation_alias(self, operation, column_name, column_alias):
return OperationDataColumnAlias.objects.create(
operation=operation, column_name=column_name, column_alias=column_alias)


@app.task(bind=False)
def create_operation_data_aliases(id):
operation = Operation.objects.get(id=id)
if not operation:
return { "status": "failed" }

count, data = query.query_table(operation, 1, 0, estimate_count=True)
try:
data_column_keys = data[0].keys()
first_step = operation.get_operation_steps()[0]
columns = SourceColumnMap.objects.filter(source=first_step.source, name__in=data_column_keys)
# delete obsolete aliases
OperationDataColumnAlias.objects.filter(operation=operation).exclude(column_name__in=data_column_keys).delete()
for column in data_column_keys:
existing_alias = OperationDataColumnAlias.objects.filter(operation=operation, column_name=column).first()
if not existing_alias:
matching = columns.filter(name=column).first()
alias = create_operation_alias(operation, column, matching.alias if matching else column)
alias.save()

return { "status": "success" }
except: # FIXME: handle specific errors
return { "status": "failed" }
2 changes: 1 addition & 1 deletion core/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class TestRestFramework(TestCase):
fixtures = ['test_data']

def setUp(self):
signals.post_save.disconnect(sender=Operation, dispatch_uid='count_operation_rows');
signals.post_save.disconnect(sender=Operation, dispatch_uid='operation__post_save');

self.user = User.objects.create_user(TEST_USER, '[email protected]', TEST_PASS)
self.superuser = User.objects.create_superuser(TEST_SUPERUSER, '[email protected]', TEST_SUPERPASS)
Expand Down
7 changes: 2 additions & 5 deletions core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ class ThemeDetail(generics.RetrieveUpdateDestroyAPIView):

class OperationList(generics.ListCreateAPIView):
"""
This view should return a list of all the operations that are not for the currently authenticated user.
This view should return a list of the published operations, including those for the currently authenticated user.
"""
authentication_classes = [TokenAuthentication]
permission_classes = (permissions.IsAuthenticatedOrReadOnly & IsOwnerOrReadOnly,)
Expand All @@ -286,10 +286,7 @@ def get_queryset(self):
"""
Filters to return the operations that are not for the currently authenticated user.
"""
if self.request.user.is_authenticated:
return Operation.objects.filter(~Q(user=self.request.user) & Q(is_draft=False)).order_by('-updated_on')
else:
return Operation.objects.filter(Q(is_draft=False)).order_by('-updated_on')
return Operation.objects.filter(Q(is_draft=False)).order_by('-updated_on')

def perform_create(self, serializer):
serializer.save(user=self.request.user)
Expand Down
14 changes: 8 additions & 6 deletions frontend/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
from django.core.signals import request_finished

from core.models import Operation
from core.tasks import count_operation_rows as count
from core.tasks import count_operation_rows as count, create_operation_data_aliases as aliases


@receiver(post_save, sender=Operation, dispatch_uid="count_operation_rows")
def count_operation_rows(sender, instance=None, created=False, **kwargs):
if instance and instance.count_rows:
count.delay(instance.id)
@receiver(post_save, sender=Operation, dispatch_uid="operation__post_save")
def operation_post_save(sender, instance=None, created=False, **kwargs):
if instance:
if instance.count_rows:
count.delay(instance.id)
aliases.delay(instance.id)

request_finished.connect(count_operation_rows, dispatch_uid="count_operation_rows")
request_finished.connect(operation_post_save, dispatch_uid="operation__post_save")
53 changes: 30 additions & 23 deletions frontend/src/components/OperationsTableCard/OperationsTableCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { bindActionCreators } from 'redux';
import { Dimmer, Loader } from 'semantic-ui-react';
import * as operationsActions from '../../actions/operations';
import { OperationsState } from '../../reducers/operations';
import { UserState } from '../../reducers/user';
import { ReduxStore } from '../../store';
import { LinksMap } from '../../types/api';
import { FormControlElement } from '../../types/bootstrap';
Expand All @@ -23,6 +24,7 @@ interface ActionProps {
}
interface ReduxState {
operations: OperationsState;
user: UserState;
}
interface ComponentProps extends RouteComponentProps {
limit: number;
Expand Down Expand Up @@ -116,31 +118,35 @@ const OperationsTableCard: FunctionComponent<OperationsTableCardProps> = (props)

const renderOperations = (operations: List<OperationMap>, allowEdit = false) => {
if (operations && operations.count()) {
return operations.map((operation, index) => (
<OperationsTableRow key={index} operation={operation} showDraftBadge={showMyQueries}>
<OperationsTableRowActions>
<DatasetActionLink operation={operation} show={allowEdit} onClick={onEditOperation}>
Edit
</DatasetActionLink>
<OverlayTrigger
placement="top"
overlay={<Popover id="view">View Dataset Data</Popover>}
>
<DatasetActionLink operation={operation} action="data" onClick={onViewData}>
View Data
return operations.map((operation, index) => {
const showEdit = allowEdit || props.user.get('username') === operation.get('user');

return (
<OperationsTableRow key={index} operation={operation} showDraftBadge={showMyQueries}>
<OperationsTableRowActions>
<DatasetActionLink operation={operation} show={showEdit} onClick={onEditOperation}>
Edit
</DatasetActionLink>
</OverlayTrigger>
<Button variant="dark" size="sm" onClick={onViewSQLQuery(operation)}>
SQL Query
</Button>
<Form action={`${api.routes.EXPORT}${operation.get('id')}/`} method="POST">
<Button type="submit" variant="dark" size="sm">
Export to CSV
<OverlayTrigger
placement="top"
overlay={<Popover id="view">View Dataset Data</Popover>}
>
<DatasetActionLink operation={operation} action="data" onClick={onViewData}>
View Data
</DatasetActionLink>
</OverlayTrigger>
<Button variant="dark" size="sm" onClick={onViewSQLQuery(operation)}>
SQL Query
</Button>
</Form>
</OperationsTableRowActions>
</OperationsTableRow>
));
<Form action={`${api.routes.EXPORT}${operation.get('id')}/`} method="POST">
<Button type="submit" variant="dark" size="sm">
Export to CSV
</Button>
</Form>
</OperationsTableRowActions>
</OperationsTableRow>
);
});
}

return <div className="px-4 pb-3">No datasets found</div>;
Expand Down Expand Up @@ -219,6 +225,7 @@ const mapDispatchToProps: MapDispatchToProps<ActionProps, ComponentProps> = (
const mapStateToProps = (reduxStore: ReduxStore): ReduxState => {
return {
operations: reduxStore.get('operations') as OperationsState,
user: reduxStore.get('user') as UserState,
};
};

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ddw-analyst-ui",
"version": "2.2.0",
"version": "2.2.1",
"description": "The new and improved DDW Analyst UI interface",
"main": "index.js",
"scripts": {
Expand Down

0 comments on commit d29cfd9

Please sign in to comment.