Skip to content

Commit

Permalink
Organize backendA files
Browse files Browse the repository at this point in the history
  • Loading branch information
pboyd committed Oct 19, 2019
1 parent 7e3653a commit 8791dce
Show file tree
Hide file tree
Showing 8 changed files with 409 additions and 383 deletions.
71 changes: 71 additions & 0 deletions backendA/airline_stats.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package main

import (
"database/sql"
"sort"
"strings"

"github.com/graphql-go/graphql"
)

func resolveFlightStatsByAirline(db *sql.DB) graphql.FieldResolveFn {
return graphQLMetrics("flightstats_by_airline",
func(p graphql.ResolveParams) (interface{}, error) {
origin, _ := p.Args["origin"].(string)
origin = strings.ToUpper(origin)

dest, _ := p.Args["destination"].(string)
dest = strings.ToUpper(dest)

if !isAirportCode(origin) || !isAirportCode(dest) {
return nil, nil
}

rows, err := db.QueryContext(p.Context,
`SELECT
carriers.name AS carrier_name, total_flights, delays_flights, last_flight
FROM
(
SELECT
carrier AS carrier_code,
SUM(total_flights) AS total_flights,
SUM(delayed_flights) AS delays_flights,
MAX(date) AS last_flight
FROM
flights_day
WHERE origin=? AND destination=?
GROUP BY carrier_code
) AS stats
INNER JOIN carriers ON carrier_code=carriers.code
`,
origin, dest)
if err != nil {
return nil, err
}
defer rows.Close()

stats := []*airlineStats{}

for rows.Next() {
var (
row airlineStats
delayedFlights int
)
err := rows.Scan(&row.Airline, &row.TotalFlights, &delayedFlights, &row.LastFlight)
if err != nil {
return nil, err
}

row.OnTimePercentage = (1.0 - float64(delayedFlights)/float64(row.TotalFlights)) * 100

stats = append(stats, &row)
}

sort.Slice(stats, func(i, j int) bool {
return stats[j].OnTimePercentage < stats[i].OnTimePercentage
})

return stats, nil
},
)
}
23 changes: 0 additions & 23 deletions backendA/airport.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,6 @@ import (
"github.com/graphql-go/graphql"
)

type airport struct {
Code string `json:"code"`
Name string `json:"name"`
City string `json:"city"`
State string `json:"state"`
Latitude string `json:"latitude"`
Longitude string `json:"longitude"`
}

var airportType = graphql.NewObject(
graphql.ObjectConfig{
Name: "Airport",
Fields: graphql.Fields{
"code": &graphql.Field{Type: graphql.String},
"name": &graphql.Field{Type: graphql.String},
"city": &graphql.Field{Type: graphql.String},
"state": &graphql.Field{Type: graphql.String},
"latitude": &graphql.Field{Type: graphql.Float},
"longitude": &graphql.Field{Type: graphql.Float},
},
},
)

func resolveAirportQuery(db *sql.DB) graphql.FieldResolveFn {
return graphQLMetrics("airport",
func(p graphql.ResolveParams) (interface{}, error) {
Expand Down
78 changes: 78 additions & 0 deletions backendA/daily_stats.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package main

import (
"database/sql"
"sort"
"strings"

"github.com/graphql-go/graphql"
)

func resolveDailyFlightStats(db *sql.DB) graphql.FieldResolveFn {
return graphQLMetrics("daily_flight_stats",
func(p graphql.ResolveParams) (interface{}, error) {
origin, _ := p.Args["origin"].(string)
origin = strings.ToUpper(origin)

dest, _ := p.Args["destination"].(string)
dest = strings.ToUpper(dest)

if !isAirportCode(origin) || !isAirportCode(dest) {
return nil, nil
}

rows, err := db.QueryContext(p.Context,
`SELECT
date,
carriers.name,
total_flights,
IF(delayed_flights IS NULL, 0, delayed_flights) AS delay_flights_not_null
FROM
flights_day
INNER JOIN carriers ON carrier=carriers.code
WHERE origin=? AND destination=?
ORDER BY date`,
origin, dest)
if err != nil {
return nil, err
}
defer rows.Close()

statsMap := map[string][]*flightStatsByDateRow{}

for rows.Next() {
var (
airline string
row flightStatsByDateRow
)

err := rows.Scan(&row.Date, &airline, &row.Flights, &row.Delays)
if err != nil {
return nil, err
}

row.OnTimePercentage = (1.0 - float64(row.Delays)/float64(row.Flights)) * 100

if statsMap[airline] == nil {
statsMap[airline] = []*flightStatsByDateRow{}
}

statsMap[airline] = append(statsMap[airline], &row)
}

stats := make([]flightStatsByDate, 0, len(statsMap))
for airline, rows := range statsMap {
stats = append(stats, flightStatsByDate{
Airline: airline,
Rows: rows,
})
}

sort.Slice(stats, func(i, j int) bool {
return stats[i].Airline < stats[j].Airline
})

return stats, nil
},
)
}
145 changes: 145 additions & 0 deletions backendA/graphql.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package main

import (
"database/sql"

"github.com/graphql-go/graphql"
)

func makeGQLSchema(db *sql.DB) (graphql.Schema, error) {
airportType := graphql.NewObject(
graphql.ObjectConfig{
Name: "Airport",
Fields: graphql.Fields{
"code": &graphql.Field{Type: graphql.String},
"name": &graphql.Field{Type: graphql.String},
"city": &graphql.Field{Type: graphql.String},
"state": &graphql.Field{Type: graphql.String},
"latitude": &graphql.Field{Type: graphql.Float},
"longitude": &graphql.Field{Type: graphql.Float},
},
},
)

airportQuery := &graphql.Field{
Type: airportType,
Description: "get airport by code",
Args: graphql.FieldConfigArgument{
"code": &graphql.ArgumentConfig{
Type: graphql.String,
Description: "airport IATA code (e.g. LAX)",
},
},
Resolve: resolveAirportQuery(db),
}

airportList := &graphql.Field{
Type: graphql.NewList(airportType),
Description: "search airports",
Args: graphql.FieldConfigArgument{
"term": &graphql.ArgumentConfig{
Type: graphql.String,
Description: "search term",
},
},
Resolve: resolveAirportList(db),
}

airlineStatsType := graphql.NewObject(
graphql.ObjectConfig{
Name: "airlineFlightStats",
Fields: graphql.Fields{
"airline": &graphql.Field{Type: graphql.String},
"totalFlights": &graphql.Field{Type: graphql.Int},
"onTimePercentage": &graphql.Field{Type: graphql.Float},
"lastFlight": &graphql.Field{Type: graphql.DateTime},
},
},
)

flightStatsByAirline := &graphql.Field{
Type: graphql.NewList(airlineStatsType),
Args: graphql.FieldConfigArgument{
"origin": &graphql.ArgumentConfig{
Type: graphql.String,
Description: "airport IATA code (e.g. LAX)",
},
"destination": &graphql.ArgumentConfig{
Type: graphql.String,
Description: "airport IATA code (e.g. LAX)",
},
},
Resolve: resolveFlightStatsByAirline(db),
}

flightStatsByDateRow := graphql.NewObject(
graphql.ObjectConfig{
Name: "flightStatsByDateRow",
Fields: graphql.Fields{
"date": &graphql.Field{Type: graphql.DateTime},
"flights": &graphql.Field{Type: graphql.Int},
"delays": &graphql.Field{Type: graphql.Int},
"onTimePercentage": &graphql.Field{Type: graphql.Float},
},
},
)

flightStatsByDate := graphql.NewList(
graphql.NewObject(
graphql.ObjectConfig{
Name: "flightStatsByDate",
Fields: graphql.Fields{
"airline": &graphql.Field{Type: graphql.String},
"rows": &graphql.Field{Type: graphql.NewList(flightStatsByDateRow)},
},
},
),
)

dailyFlightStats := &graphql.Field{
Type: flightStatsByDate,
Args: graphql.FieldConfigArgument{
"origin": &graphql.ArgumentConfig{
Type: graphql.String,
Description: "airport IATA code (e.g. LAX)",
},
"destination": &graphql.ArgumentConfig{
Type: graphql.String,
Description: "airport IATA code (e.g. LAX)",
},
},
Resolve: resolveDailyFlightStats(db),
}

monthlyFlightStats := &graphql.Field{
Type: flightStatsByDate,
Args: graphql.FieldConfigArgument{
"origin": &graphql.ArgumentConfig{
Type: graphql.String,
Description: "airport IATA code (e.g. LAX)",
},
"destination": &graphql.ArgumentConfig{
Type: graphql.String,
Description: "airport IATA code (e.g. LAX)",
},
},
Resolve: resolveMonthlyFlightStats(db),
}

return graphql.NewSchema(
graphql.SchemaConfig{
Query: graphql.NewObject(
graphql.ObjectConfig{
Name: "Query",
Fields: graphql.Fields{
"airport": airportQuery,
"airportList": airportList,
"flightStatsByAirline": flightStatsByAirline,
"dailyFlightStats": dailyFlightStats,
"monthlyFlightStats": monthlyFlightStats,
},
},
),
},
)
}
Loading

0 comments on commit 8791dce

Please sign in to comment.