Docker-DCO-1.1-Signed-off-by: Bryan Murphy <bmurphy1976@gmail.com> (github: bmurphy1976)
| ... | ... |
@@ -5,7 +5,6 @@ import ( |
| 5 | 5 |
"encoding/json" |
| 6 | 6 |
"fmt" |
| 7 | 7 |
"io" |
| 8 |
- "sort" |
|
| 9 | 8 |
"strconv" |
| 10 | 9 |
"strings" |
| 11 | 10 |
) |
| ... | ... |
@@ -251,135 +250,3 @@ func (env *Env) Map() map[string]string {
|
| 251 | 251 |
} |
| 252 | 252 |
return m |
| 253 | 253 |
} |
| 254 |
- |
|
| 255 |
-type Table struct {
|
|
| 256 |
- Data []*Env |
|
| 257 |
- sortKey string |
|
| 258 |
- Chan chan *Env |
|
| 259 |
-} |
|
| 260 |
- |
|
| 261 |
-func NewTable(sortKey string, sizeHint int) *Table {
|
|
| 262 |
- return &Table{
|
|
| 263 |
- make([]*Env, 0, sizeHint), |
|
| 264 |
- sortKey, |
|
| 265 |
- make(chan *Env), |
|
| 266 |
- } |
|
| 267 |
-} |
|
| 268 |
- |
|
| 269 |
-func (t *Table) SetKey(sortKey string) {
|
|
| 270 |
- t.sortKey = sortKey |
|
| 271 |
-} |
|
| 272 |
- |
|
| 273 |
-func (t *Table) Add(env *Env) {
|
|
| 274 |
- t.Data = append(t.Data, env) |
|
| 275 |
-} |
|
| 276 |
- |
|
| 277 |
-func (t *Table) Len() int {
|
|
| 278 |
- return len(t.Data) |
|
| 279 |
-} |
|
| 280 |
- |
|
| 281 |
-func (t *Table) Less(a, b int) bool {
|
|
| 282 |
- return t.lessBy(a, b, t.sortKey) |
|
| 283 |
-} |
|
| 284 |
- |
|
| 285 |
-func (t *Table) lessBy(a, b int, by string) bool {
|
|
| 286 |
- keyA := t.Data[a].Get(by) |
|
| 287 |
- keyB := t.Data[b].Get(by) |
|
| 288 |
- intA, errA := strconv.ParseInt(keyA, 10, 64) |
|
| 289 |
- intB, errB := strconv.ParseInt(keyB, 10, 64) |
|
| 290 |
- if errA == nil && errB == nil {
|
|
| 291 |
- return intA < intB |
|
| 292 |
- } |
|
| 293 |
- return keyA < keyB |
|
| 294 |
-} |
|
| 295 |
- |
|
| 296 |
-func (t *Table) Swap(a, b int) {
|
|
| 297 |
- tmp := t.Data[a] |
|
| 298 |
- t.Data[a] = t.Data[b] |
|
| 299 |
- t.Data[b] = tmp |
|
| 300 |
-} |
|
| 301 |
- |
|
| 302 |
-func (t *Table) Sort() {
|
|
| 303 |
- sort.Sort(t) |
|
| 304 |
-} |
|
| 305 |
- |
|
| 306 |
-func (t *Table) ReverseSort() {
|
|
| 307 |
- sort.Sort(sort.Reverse(t)) |
|
| 308 |
-} |
|
| 309 |
- |
|
| 310 |
-func (t *Table) WriteListTo(dst io.Writer) (n int64, err error) {
|
|
| 311 |
- if _, err := dst.Write([]byte{'['}); err != nil {
|
|
| 312 |
- return -1, err |
|
| 313 |
- } |
|
| 314 |
- n = 1 |
|
| 315 |
- for i, env := range t.Data {
|
|
| 316 |
- bytes, err := env.WriteTo(dst) |
|
| 317 |
- if err != nil {
|
|
| 318 |
- return -1, err |
|
| 319 |
- } |
|
| 320 |
- n += bytes |
|
| 321 |
- if i != len(t.Data)-1 {
|
|
| 322 |
- if _, err := dst.Write([]byte{','}); err != nil {
|
|
| 323 |
- return -1, err |
|
| 324 |
- } |
|
| 325 |
- n += 1 |
|
| 326 |
- } |
|
| 327 |
- } |
|
| 328 |
- if _, err := dst.Write([]byte{']'}); err != nil {
|
|
| 329 |
- return -1, err |
|
| 330 |
- } |
|
| 331 |
- return n + 1, nil |
|
| 332 |
-} |
|
| 333 |
- |
|
| 334 |
-func (t *Table) ToListString() (string, error) {
|
|
| 335 |
- buffer := bytes.NewBuffer(nil) |
|
| 336 |
- if _, err := t.WriteListTo(buffer); err != nil {
|
|
| 337 |
- return "", err |
|
| 338 |
- } |
|
| 339 |
- return buffer.String(), nil |
|
| 340 |
-} |
|
| 341 |
- |
|
| 342 |
-func (t *Table) WriteTo(dst io.Writer) (n int64, err error) {
|
|
| 343 |
- for _, env := range t.Data {
|
|
| 344 |
- bytes, err := env.WriteTo(dst) |
|
| 345 |
- if err != nil {
|
|
| 346 |
- return -1, err |
|
| 347 |
- } |
|
| 348 |
- n += bytes |
|
| 349 |
- } |
|
| 350 |
- return n, nil |
|
| 351 |
-} |
|
| 352 |
- |
|
| 353 |
-func (t *Table) ReadListFrom(src []byte) (n int64, err error) {
|
|
| 354 |
- var array []interface{}
|
|
| 355 |
- |
|
| 356 |
- if err := json.Unmarshal(src, &array); err != nil {
|
|
| 357 |
- return -1, err |
|
| 358 |
- } |
|
| 359 |
- |
|
| 360 |
- for _, item := range array {
|
|
| 361 |
- if m, ok := item.(map[string]interface{}); ok {
|
|
| 362 |
- env := &Env{}
|
|
| 363 |
- for key, value := range m {
|
|
| 364 |
- env.SetAuto(key, value) |
|
| 365 |
- } |
|
| 366 |
- t.Add(env) |
|
| 367 |
- } |
|
| 368 |
- } |
|
| 369 |
- |
|
| 370 |
- return int64(len(src)), nil |
|
| 371 |
-} |
|
| 372 |
- |
|
| 373 |
-func (t *Table) ReadFrom(src io.Reader) (n int64, err error) {
|
|
| 374 |
- decoder := NewDecoder(src) |
|
| 375 |
- for {
|
|
| 376 |
- env, err := decoder.Decode() |
|
| 377 |
- if err == io.EOF {
|
|
| 378 |
- return 0, nil |
|
| 379 |
- } else if err != nil {
|
|
| 380 |
- return -1, err |
|
| 381 |
- } |
|
| 382 |
- t.Add(env) |
|
| 383 |
- } |
|
| 384 |
- return 0, nil |
|
| 385 |
-} |
| 386 | 254 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,141 @@ |
| 0 |
+package engine |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "bytes" |
|
| 4 |
+ "encoding/json" |
|
| 5 |
+ "io" |
|
| 6 |
+ "sort" |
|
| 7 |
+ "strconv" |
|
| 8 |
+) |
|
| 9 |
+ |
|
| 10 |
+type Table struct {
|
|
| 11 |
+ Data []*Env |
|
| 12 |
+ sortKey string |
|
| 13 |
+ Chan chan *Env |
|
| 14 |
+} |
|
| 15 |
+ |
|
| 16 |
+func NewTable(sortKey string, sizeHint int) *Table {
|
|
| 17 |
+ return &Table{
|
|
| 18 |
+ make([]*Env, 0, sizeHint), |
|
| 19 |
+ sortKey, |
|
| 20 |
+ make(chan *Env), |
|
| 21 |
+ } |
|
| 22 |
+} |
|
| 23 |
+ |
|
| 24 |
+func (t *Table) SetKey(sortKey string) {
|
|
| 25 |
+ t.sortKey = sortKey |
|
| 26 |
+} |
|
| 27 |
+ |
|
| 28 |
+func (t *Table) Add(env *Env) {
|
|
| 29 |
+ t.Data = append(t.Data, env) |
|
| 30 |
+} |
|
| 31 |
+ |
|
| 32 |
+func (t *Table) Len() int {
|
|
| 33 |
+ return len(t.Data) |
|
| 34 |
+} |
|
| 35 |
+ |
|
| 36 |
+func (t *Table) Less(a, b int) bool {
|
|
| 37 |
+ return t.lessBy(a, b, t.sortKey) |
|
| 38 |
+} |
|
| 39 |
+ |
|
| 40 |
+func (t *Table) lessBy(a, b int, by string) bool {
|
|
| 41 |
+ keyA := t.Data[a].Get(by) |
|
| 42 |
+ keyB := t.Data[b].Get(by) |
|
| 43 |
+ intA, errA := strconv.ParseInt(keyA, 10, 64) |
|
| 44 |
+ intB, errB := strconv.ParseInt(keyB, 10, 64) |
|
| 45 |
+ if errA == nil && errB == nil {
|
|
| 46 |
+ return intA < intB |
|
| 47 |
+ } |
|
| 48 |
+ return keyA < keyB |
|
| 49 |
+} |
|
| 50 |
+ |
|
| 51 |
+func (t *Table) Swap(a, b int) {
|
|
| 52 |
+ tmp := t.Data[a] |
|
| 53 |
+ t.Data[a] = t.Data[b] |
|
| 54 |
+ t.Data[b] = tmp |
|
| 55 |
+} |
|
| 56 |
+ |
|
| 57 |
+func (t *Table) Sort() {
|
|
| 58 |
+ sort.Sort(t) |
|
| 59 |
+} |
|
| 60 |
+ |
|
| 61 |
+func (t *Table) ReverseSort() {
|
|
| 62 |
+ sort.Sort(sort.Reverse(t)) |
|
| 63 |
+} |
|
| 64 |
+ |
|
| 65 |
+func (t *Table) WriteListTo(dst io.Writer) (n int64, err error) {
|
|
| 66 |
+ if _, err := dst.Write([]byte{'['}); err != nil {
|
|
| 67 |
+ return -1, err |
|
| 68 |
+ } |
|
| 69 |
+ n = 1 |
|
| 70 |
+ for i, env := range t.Data {
|
|
| 71 |
+ bytes, err := env.WriteTo(dst) |
|
| 72 |
+ if err != nil {
|
|
| 73 |
+ return -1, err |
|
| 74 |
+ } |
|
| 75 |
+ n += bytes |
|
| 76 |
+ if i != len(t.Data)-1 {
|
|
| 77 |
+ if _, err := dst.Write([]byte{','}); err != nil {
|
|
| 78 |
+ return -1, err |
|
| 79 |
+ } |
|
| 80 |
+ n += 1 |
|
| 81 |
+ } |
|
| 82 |
+ } |
|
| 83 |
+ if _, err := dst.Write([]byte{']'}); err != nil {
|
|
| 84 |
+ return -1, err |
|
| 85 |
+ } |
|
| 86 |
+ return n + 1, nil |
|
| 87 |
+} |
|
| 88 |
+ |
|
| 89 |
+func (t *Table) ToListString() (string, error) {
|
|
| 90 |
+ buffer := bytes.NewBuffer(nil) |
|
| 91 |
+ if _, err := t.WriteListTo(buffer); err != nil {
|
|
| 92 |
+ return "", err |
|
| 93 |
+ } |
|
| 94 |
+ return buffer.String(), nil |
|
| 95 |
+} |
|
| 96 |
+ |
|
| 97 |
+func (t *Table) WriteTo(dst io.Writer) (n int64, err error) {
|
|
| 98 |
+ for _, env := range t.Data {
|
|
| 99 |
+ bytes, err := env.WriteTo(dst) |
|
| 100 |
+ if err != nil {
|
|
| 101 |
+ return -1, err |
|
| 102 |
+ } |
|
| 103 |
+ n += bytes |
|
| 104 |
+ } |
|
| 105 |
+ return n, nil |
|
| 106 |
+} |
|
| 107 |
+ |
|
| 108 |
+func (t *Table) ReadListFrom(src []byte) (n int64, err error) {
|
|
| 109 |
+ var array []interface{}
|
|
| 110 |
+ |
|
| 111 |
+ if err := json.Unmarshal(src, &array); err != nil {
|
|
| 112 |
+ return -1, err |
|
| 113 |
+ } |
|
| 114 |
+ |
|
| 115 |
+ for _, item := range array {
|
|
| 116 |
+ if m, ok := item.(map[string]interface{}); ok {
|
|
| 117 |
+ env := &Env{}
|
|
| 118 |
+ for key, value := range m {
|
|
| 119 |
+ env.SetAuto(key, value) |
|
| 120 |
+ } |
|
| 121 |
+ t.Add(env) |
|
| 122 |
+ } |
|
| 123 |
+ } |
|
| 124 |
+ |
|
| 125 |
+ return int64(len(src)), nil |
|
| 126 |
+} |
|
| 127 |
+ |
|
| 128 |
+func (t *Table) ReadFrom(src io.Reader) (n int64, err error) {
|
|
| 129 |
+ decoder := NewDecoder(src) |
|
| 130 |
+ for {
|
|
| 131 |
+ env, err := decoder.Decode() |
|
| 132 |
+ if err == io.EOF {
|
|
| 133 |
+ return 0, nil |
|
| 134 |
+ } else if err != nil {
|
|
| 135 |
+ return -1, err |
|
| 136 |
+ } |
|
| 137 |
+ t.Add(env) |
|
| 138 |
+ } |
|
| 139 |
+ return 0, nil |
|
| 140 |
+} |
| ... | ... |
@@ -26,3 +26,87 @@ func TestTableWriteTo(t *testing.T) {
|
| 26 | 26 |
t.Fatalf("Inccorect output: %v", output)
|
| 27 | 27 |
} |
| 28 | 28 |
} |
| 29 |
+ |
|
| 30 |
+func TestTableSortStringValue(t *testing.T) {
|
|
| 31 |
+ table := NewTable("Key", 0)
|
|
| 32 |
+ |
|
| 33 |
+ e := &Env{}
|
|
| 34 |
+ e.Set("Key", "A")
|
|
| 35 |
+ table.Add(e) |
|
| 36 |
+ |
|
| 37 |
+ e = &Env{}
|
|
| 38 |
+ e.Set("Key", "D")
|
|
| 39 |
+ table.Add(e) |
|
| 40 |
+ |
|
| 41 |
+ e = &Env{}
|
|
| 42 |
+ e.Set("Key", "B")
|
|
| 43 |
+ table.Add(e) |
|
| 44 |
+ |
|
| 45 |
+ e = &Env{}
|
|
| 46 |
+ e.Set("Key", "C")
|
|
| 47 |
+ table.Add(e) |
|
| 48 |
+ |
|
| 49 |
+ table.Sort() |
|
| 50 |
+ |
|
| 51 |
+ if len := table.Len(); len != 4 {
|
|
| 52 |
+ t.Fatalf("Expected 4, got %d", len)
|
|
| 53 |
+ } |
|
| 54 |
+ |
|
| 55 |
+ if value := table.Data[0].Get("Key"); value != "A" {
|
|
| 56 |
+ t.Fatalf("Expected A, got %s", value)
|
|
| 57 |
+ } |
|
| 58 |
+ |
|
| 59 |
+ if value := table.Data[1].Get("Key"); value != "B" {
|
|
| 60 |
+ t.Fatalf("Expected B, got %s", value)
|
|
| 61 |
+ } |
|
| 62 |
+ |
|
| 63 |
+ if value := table.Data[2].Get("Key"); value != "C" {
|
|
| 64 |
+ t.Fatalf("Expected C, got %s", value)
|
|
| 65 |
+ } |
|
| 66 |
+ |
|
| 67 |
+ if value := table.Data[3].Get("Key"); value != "D" {
|
|
| 68 |
+ t.Fatalf("Expected D, got %s", value)
|
|
| 69 |
+ } |
|
| 70 |
+} |
|
| 71 |
+ |
|
| 72 |
+func TestTableReverseSortStringValue(t *testing.T) {
|
|
| 73 |
+ table := NewTable("Key", 0)
|
|
| 74 |
+ |
|
| 75 |
+ e := &Env{}
|
|
| 76 |
+ e.Set("Key", "A")
|
|
| 77 |
+ table.Add(e) |
|
| 78 |
+ |
|
| 79 |
+ e = &Env{}
|
|
| 80 |
+ e.Set("Key", "D")
|
|
| 81 |
+ table.Add(e) |
|
| 82 |
+ |
|
| 83 |
+ e = &Env{}
|
|
| 84 |
+ e.Set("Key", "B")
|
|
| 85 |
+ table.Add(e) |
|
| 86 |
+ |
|
| 87 |
+ e = &Env{}
|
|
| 88 |
+ e.Set("Key", "C")
|
|
| 89 |
+ table.Add(e) |
|
| 90 |
+ |
|
| 91 |
+ table.ReverseSort() |
|
| 92 |
+ |
|
| 93 |
+ if len := table.Len(); len != 4 {
|
|
| 94 |
+ t.Fatalf("Expected 4, got %d", len)
|
|
| 95 |
+ } |
|
| 96 |
+ |
|
| 97 |
+ if value := table.Data[0].Get("Key"); value != "D" {
|
|
| 98 |
+ t.Fatalf("Expected D, got %s", value)
|
|
| 99 |
+ } |
|
| 100 |
+ |
|
| 101 |
+ if value := table.Data[1].Get("Key"); value != "C" {
|
|
| 102 |
+ t.Fatalf("Expected B, got %s", value)
|
|
| 103 |
+ } |
|
| 104 |
+ |
|
| 105 |
+ if value := table.Data[2].Get("Key"); value != "B" {
|
|
| 106 |
+ t.Fatalf("Expected C, got %s", value)
|
|
| 107 |
+ } |
|
| 108 |
+ |
|
| 109 |
+ if value := table.Data[3].Get("Key"); value != "A" {
|
|
| 110 |
+ t.Fatalf("Expected A, got %s", value)
|
|
| 111 |
+ } |
|
| 112 |
+} |