Advertisement
jkonefal

Untitled

Apr 13th, 2022
3,194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 5.76 KB | None | 0 0
  1. #lang racket
  2.  
  3. (provide (struct-out column-info)
  4.          (struct-out table)
  5.          (struct-out and-f)
  6.          (struct-out or-f)
  7.          (struct-out not-f)
  8.          (struct-out eq-f)
  9.          (struct-out eq2-f)
  10.          (struct-out lt-f)
  11.          table-insert
  12.          table-project
  13.          table-sort
  14.          table-select
  15.          table-rename
  16.          table-cross-join
  17.          table-natural-join)
  18.  
  19. (define-struct column-info (name type) #:transparent)
  20.  
  21. (define-struct table (schema rows) #:transparent)
  22.  
  23. (define cities
  24.   (table
  25.    (list (column-info 'city    'string)
  26.          (column-info 'country 'string)
  27.          (column-info 'area    'number)
  28.          (column-info 'capital 'boolean))
  29.    (list (list "Wrocław" "Poland"  293 #f)
  30.          (list "Warsaw"  "Poland"  517 #t)
  31.          (list "Poznań"  "Poland"  262 #f)
  32.          (list "Berlin"  "Germany" 892 #t)
  33.          (list "Munich"  "Germany" 310 #f)
  34.          (list "Paris"   "France"  105 #t)
  35.          (list "Rennes"  "France"   50 #f))))
  36.  
  37. (define countries
  38.   (table
  39.    (list (column-info 'country 'string)
  40.          (column-info 'population 'number))
  41.    (list (list "Poland" 38)
  42.          (list "Germany" 83)
  43.          (list "France" 67)
  44.          (list "Spain" 47))))
  45.  
  46. (define (empty-table columns) (table columns '()))
  47.  
  48. ; Wstawianie
  49.  
  50. (define (val-type-ok? val type)
  51.   (cond ([and (eq? type 'number) (number? val)] true)
  52.         ([and (eq? type 'string) (string? val)] true)
  53.         ([and (eq? type 'symbol) (symbol? val)] true)
  54.         ([and (eq? type 'boolean) (boolean? val)] true)
  55.         (else false)))
  56.  
  57. (define (type-ok? row schema)
  58.   (cond ([and (empty? row) (empty? schema)] true)
  59.         ([or (empty? row) (empty? schema)] false)
  60.         ([val-type-ok? (car row) (column-info-type (car schema))] (type-ok? (cdr row) (cdr schema)))
  61.         (else false)))
  62.  
  63. (define (table-insert row tab)
  64.   (if (type-ok? row (table-schema tab))
  65.       (table (table-schema tab) (cons row (table-rows tab)))
  66.       (error "invalid row types")))
  67.  
  68.  
  69. ; Projekcja
  70. (define (column-name-to-id name schema)
  71.   (define (cmp-names column name) (equal? name (column-info-name column)))
  72.   (index-of schema name cmp-names))
  73.  
  74. (define (column-names-to-ids names schema)
  75.   (map (lambda (n) (column-name-to-id n schema)) names))
  76.  
  77. (define (table-project xs tab)
  78.   (define ids (column-names-to-ids xs (table-schema tab)))
  79.   (define schema (map (lambda (id) (list-ref (table-schema tab) id)) ids))
  80.   (define rows (map (lambda (row)
  81.     (map (lambda (id) (list-ref row id)) ids))
  82.   (table-rows tab)))
  83.   (table schema rows))
  84.  
  85.  
  86. ;; Sortowanie
  87. (define (compare val1 val2)
  88.   (cond ([integer? val1] (< val1 val2))
  89.         ([string? val1] (string<? val1 val2))
  90.         ([symbol? val1] (symbol<? val1 val2))
  91.         (else (and (not val1) val2))))
  92.  
  93. (define (sort1 col tab)
  94.   (define id (column-name-to-id col (table-schema tab)))
  95.   (define rows (sort (table-rows tab) (lambda (x y) (compare (list-ref x id) (list-ref y id)))))
  96.   (table (table-schema tab) rows))
  97.  
  98. (define (table-sort cols tab)
  99.   (if (empty? cols)
  100.       tab
  101.       (sort1 (car cols) (table-sort (cdr cols) tab))))
  102. ;; Selekcja
  103.  
  104. (define-struct and-f (l r))
  105. (define-struct or-f (l r))
  106. (define-struct not-f (e))
  107. (define-struct eq-f (name val))
  108. (define-struct eq2-f (name name2))
  109. (define-struct lt-f (name val))
  110. ;
  111. (define (matches? formula schema row)
  112.   (match formula
  113.     ([and-f l r] (and (matches? l schema row) (matches? r schema row)))
  114.     ([or-f l r] (or (matches? l schema row) (matches? r schema row)))
  115.     ([not-f e] (not (matches? e schema row)))
  116.     ([eq-f name val] (equal? (list-ref row (column-name-to-id name schema)) val))
  117.     ([eq2-f name name2] (equal? (list-ref row (column-name-to-id name schema)) (list-ref row (column-name-to-id name2 schema))))
  118.     ([lt-f name val] (compare (list-ref row (column-name-to-id name schema)) val))
  119.     (else false)))
  120.  
  121. (define (table-select formula tab)
  122.   (define schema (table-schema tab))
  123.   (define rows (filter (lambda (row) (matches? formula schema row)) (table-rows tab)))
  124.   (table schema rows))
  125.  
  126.  
  127. ;; Zmiana nazwy
  128. (define (table-rename old-name new-name tab)
  129.   (define (rename-column column)
  130.     (if (eq? (column-info-name column) old-name)
  131.         (column-info new-name (column-info-type column))
  132.         column))
  133.   (define schema (map rename-column (table-schema tab)))
  134.   (table schema (table-rows tab)))
  135.  
  136.  
  137. ;; Złączenie kartezjańskie
  138.  
  139. (define (table-cross-join tab1 tab2)
  140.   (define schema (append (table-schema tab1) (table-schema tab2)))
  141.   (define rows (append-map
  142.     (lambda (row1) (map
  143.       (lambda (row2) (append row1 row2))
  144.       (table-rows tab2)))
  145.     (table-rows tab1)))
  146.   (table schema rows))  
  147.  
  148. ; Złączenie
  149.  
  150. (define (table-natural-join tab1 tab2)
  151.  (define columns1 (map column-info-name (table-schema tab1)))
  152.   (define columns2 (map column-info-name (table-schema tab2)))
  153.   (define column-intersection (set-intersect columns1 columns2))
  154.   (define (add2 sym) (string->symbol (string-append (symbol->string sym) "2")))
  155.   (define column-intersection2 (map add2 column-intersection))
  156.   (define (add2-tab xs tab)
  157.     (if (empty? xs)
  158.         tab
  159.         (add2-tab (cdr xs) (table-rename (car xs) (add2 (car xs)) tab))))
  160.   (define tab3 (table-cross-join tab1 (add2-tab column-intersection tab2)))
  161.   (define columns3 (map column-info-name (table-schema tab3)))
  162.   (define ids1 (column-names-to-ids column-intersection (table-schema tab3)))
  163.   (define ids2 (column-names-to-ids column-intersection2 (table-schema tab3)))
  164.   (define (row-ok? row) (andmap (lambda (id1 id2) (equal? (list-ref row id1) (list-ref row id2))) ids1 ids2))
  165.   (define tab4 (table (table-schema tab3) (filter row-ok? (table-rows tab3))))
  166.   (table-project (set-subtract columns3 column-intersection2) tab4))
  167.  
  168.  
  169.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement