Skip to content

Commit

Permalink
SQL studio component and backend implementation
Browse files Browse the repository at this point in the history
Plus the ability to handle (almost) all MySQL types without triggering errors ...
  • Loading branch information
Thomas Hansen committed Sep 1, 2019
1 parent 060cfe0 commit 7c7ff3b
Show file tree
Hide file tree
Showing 16 changed files with 293 additions and 30 deletions.
2 changes: 2 additions & 0 deletions frontend/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import { HomeComponent } from './components/home/home.component';
import { EvaluatorComponent } from './components/evaluator/evaluator.component';
import { FilesComponent } from './components/files/files.component';
import { CrudifyComponent } from './components/crudify/crudify.component';
import { SqlComponent } from './components/sql/sql.component';

const routes: Routes = [
{ path: 'files', component: FilesComponent },
{ path: 'crudify', component: CrudifyComponent },
{ path: 'endpoints', component: EndpointsComponent },
{ path: 'evaluator', component: EvaluatorComponent },
{ path: 'sql', component: SqlComponent },
{ path: '', component: HomeComponent }
];

Expand Down
7 changes: 7 additions & 0 deletions frontend/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@
routerLinkActive="active-link"
[routerLinkActiveOptions]="{exact:true}">Endpoints</a>

<a
*ngIf="isLoggedIn()"
mat-button
routerLink="/sql"
routerLinkActive="active-link"
[routerLinkActiveOptions]="{exact:true}">SQL</a>

<a
*ngIf="isLoggedIn()"
mat-button
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import { FilesComponent } from './components/files/files.component';
import { NewFileDialog } from './components/files/files.component';
import { CrudifyComponent } from './components/crudify/crudify.component';
import { environment } from 'src/environments/environment';
import { SqlComponent } from './components/sql/sql.component';
import { DynamicPipe } from './pipes/dynamic.pipe';

export function tokenGetter() {
return localStorage.getItem("access_token");
Expand All @@ -43,6 +45,8 @@ export function tokenGetter() {
FilesComponent,
NewFileDialog,
CrudifyComponent,
SqlComponent,
DynamicPipe,
],
imports: [
BrowserModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<mat-checkbox
[(ngModel)]="showSystemEndpoints">Show system endpoints</mat-checkbox>
</label>

<table mat-table [dataSource]="getFilteredEndpoints()">

<ng-container matColumnDef="url">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
.active-wrapper {
padding:0 5rem 2rem 5rem;
.view-endpoint-card {
padding-top: 3rem;
position: relative;
.fill-width {
width: 100%;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

<div class="evaluator-wrapper">

<div class="mat-elevation-z4">
<div class="mat-elevation-z4 no-codemirror-auto-height">

<ngx-codemirror
[(ngModel)]="hyperlambda"
Expand All @@ -19,7 +19,7 @@

<div *ngIf="result !== null" class="result-wrapper">

<div class="mat-elevation-z4">
<div class="mat-elevation-z4 no-codemirror-auto-height">
<ngx-codemirror
[(ngModel)]="result"
[options]="getCodeMirrorOptions()"></ngx-codemirror>
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/app/components/evaluator/evaluator.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ export class EvaluatorComponent implements OnInit {
private service: EvaluatorService,
private snackBar: MatSnackBar) { }

ngOnInit() {
}
ngOnInit() { }

evaluate() {
this.service.evaluate(this.hyperlambda).subscribe((res) => {
Expand Down
30 changes: 30 additions & 0 deletions frontend/src/app/components/sql/sql.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

<div class="mat-elevation-z4 sql no-codemirror-auto-height">

<ngx-codemirror
[(ngModel)]="sqlText"
[options]="getCodeMirrorOptions()"></ngx-codemirror>

</div>

<div class="right-aligned">
<button
mat-button
matTooltip="Evaluates your Hyperlambda"
(click)="evaluate()">Evaluate</button>
</div>

<div *ngIf="result !== null && result.length > 0" class="mat-elevation-z4 result">
<table class="fill-width">
<tr>
<th *ngFor="let idx of result[0] | dynamic">
{{idx.key}}
</th>
</tr>
<tr *ngFor="let row of result">
<td *ngFor="let idx of row | dynamic">
{{idx.value}}
</td>
</tr>
</table>
</div>
27 changes: 27 additions & 0 deletions frontend/src/app/components/sql/sql.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

.sql {
margin:5rem 4rem .5rem 4rem;
}

.right-aligned {
margin:0 4rem .5rem 4rem;
text-align: right;
}

.result {
margin:.5rem 4rem .5rem 4rem;
padding: 3rem;
table.fill-width {
width: 100%;
tr {
th {
text-align: left;
}
}
}
}

::ng-deep .error-snackbar {
background:rgb(255,100,100);
color:rgb(0,0,0);
}
56 changes: 56 additions & 0 deletions frontend/src/app/components/sql/sql.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

import { Component, OnInit } from '@angular/core';
import { PipeTransform, Pipe } from '@angular/core';
import { MatSnackBar } from '@angular/material';
import { SqlService } from 'src/app/services/sql-service';

@Component({
selector: 'app-sql',
templateUrl: './sql.component.html',
styleUrls: ['./sql.component.scss']
})
export class SqlComponent implements OnInit {
private result: any = null;
private sqlText: string = `/*
* Type your SQL in here
*/
use some_database;
select * from some_table;`;

constructor(
private sqlService: SqlService,
private snackBar: MatSnackBar) { }

ngOnInit() { }

getCodeMirrorOptions() {
return {
lineNumbers: true,
theme: 'material',
height: '250px',
mode: 'text/x-mysql',
};
}

evaluate() {
this.sqlService.evaluate(this.sqlText).subscribe((res) => {
this.result = res;
this.showHttpSuccess('SQL executed successfully');
}, (error) => {
this.showHttpError(error);
});
}

showHttpError(error: any) {
this.snackBar.open(error.error.message, 'Close', {
duration: 10000,
panelClass: ['error-snackbar'],
});
}

showHttpSuccess(msg: string) {
this.snackBar.open(msg, 'Close', {
duration: 2000,
});
}
}
14 changes: 14 additions & 0 deletions frontend/src/app/pipes/dynamic.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: 'dynamic'
})
export class DynamicPipe implements PipeTransform {
transform(value: any, args: string[]) : any {
let keys = [];
for (let key in value) {
keys.push({key: key, value: value[key]});
}
return keys;
}
}
20 changes: 20 additions & 0 deletions frontend/src/app/services/sql-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';

@Injectable({
providedIn: 'root'
})
export class SqlService {

constructor(private httpClient: HttpClient) { }

public evaluate(sql: string) {
return this.httpClient.post<any[]>(
environment.apiURL +
'hl/system/db/evaluate', {
sql,
});
}
}
1 change: 1 addition & 0 deletions frontend/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { environment } from './environments/environment';

import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/markdown/markdown';
import 'codemirror/mode/sql/sql';

if (environment.production) {
enableProdMode();
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
.CodeMirror {
height: auto;
}

.no-codemirror-auto-height .CodeMirror {
height: 350px;
}
106 changes: 81 additions & 25 deletions magic.backend/files/modules/system/db/crudify.post.hl
Original file line number Diff line number Diff line change
Expand Up @@ -22,43 +22,99 @@ auth.verify-ticket:root
* Making sure we transform template arguments to something we can understand.
*/
for-each:x:@.arguments/*/args/**
switch:x:@.dp/#


/*
* Everything transformed into integer long values.
*/
case:int(11)
case:int(10) unsigned
set-value:x:@.dp/#
.:long
/*
* Making sure this is a valid noe (that it has values).
*/
if
not
eq
get-value:x:@.dp/#
.
.lambda


/*
* Default implementation.
*/
default
if
eq
get-name:x:@.dp/#
.:
.lambda
/*
* Making sure we get rid of resolution.
*/
regex-replace:x:@.dp/#
what:\([0-9,]+\)
with:
switch:x:@regex-replace

set-name:x:@.dp/#
get-value:x:@.dp/#

/*
* Everything transformed into date values.
*/
case:date
case:datetime
set-value:x:@.dp/#
.:date

else-if
not
eq
get-value:x:@.dp/#
.
.lambda

/*
* Everything transformed into decimal values.
*/
case:float
case:double
case:double precision
case:decimal
case:dec
set-value:x:@.dp/#
.:decimal


/*
* Everything transformed into integer long values.
*/
case:bit
case:tinyint
case:bool
case:boolean
case:smallint
case:mediumint
case:integer
case:bigint
case:int
case:int unsigned
set-value:x:@.dp/#
.:long


/*
* Everything transformed into string values.
*/
case:char
case:varchar
case:binary
case:varbinary
case:tinyblob
case:tinytext
case:text
case:blob
case:mediumtext
case:mediumblob
case:longtext
case:longblob
case:enum
case:set
set-value:x:@.dp/#
.:string


/*
* These are unsupported column types.
*/
default
.ex
set-value:x:@.ex
concat
get-value:x:@.dp/#
.:" is currently not supported by the crudifier"
throw:x:@.ex


/*
* Creating our endpoint according to arguments given, by using [apply-file]
* on the [template] file given.
Expand Down
Loading

0 comments on commit 7c7ff3b

Please sign in to comment.