km-db 0.2.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +2 -4
  5. data/Gemfile.lock +179 -20
  6. data/Procfile +2 -0
  7. data/Procfile.work +1 -0
  8. data/README.md +186 -0
  9. data/Rakefile +1 -0
  10. data/bin/kmdb-flush +13 -0
  11. data/bin/kmdb-import +13 -0
  12. data/bin/kmdb-partition +15 -0
  13. data/bin/kmdb-pool +8 -0
  14. data/bin/kmdb-realias +12 -0
  15. data/bin/kmdb-ui +6 -0
  16. data/bin/kmdb-work +17 -0
  17. data/config/amazon-rds-ca-cert.pem +260 -0
  18. data/config.ru +8 -0
  19. data/km-db.gemspec +17 -17
  20. data/lib/kmdb/{belongs_to_user.rb → concerns/belongs_to_user.rb} +3 -3
  21. data/lib/kmdb/concerns/has_properties.rb +35 -0
  22. data/lib/kmdb/jobs/find_files.rb +32 -0
  23. data/lib/kmdb/jobs/list_files.rb +37 -0
  24. data/lib/kmdb/jobs/locked.rb +10 -0
  25. data/lib/kmdb/jobs/parse_file.rb +109 -0
  26. data/lib/kmdb/jobs/record_batch.rb +65 -0
  27. data/lib/kmdb/jobs/redo_unaliasing.rb +31 -0
  28. data/lib/kmdb/jobs/unalias_user.rb +32 -0
  29. data/lib/kmdb/migrations/01_kmdb_initial.rb +78 -0
  30. data/lib/kmdb/migrations/02_kmdb_partitions.rb +28 -0
  31. data/lib/kmdb/migrations/03_kmdb_blacklist.rb +20 -0
  32. data/lib/kmdb/models/alias.rb +36 -0
  33. data/lib/kmdb/models/blacklisted_property.rb +20 -0
  34. data/lib/kmdb/models/custom_record.rb +53 -0
  35. data/lib/kmdb/models/dumpfile.rb +33 -0
  36. data/lib/kmdb/models/event.rb +56 -0
  37. data/lib/kmdb/models/event_batch.rb +72 -0
  38. data/lib/kmdb/models/global_uid.rb +42 -0
  39. data/lib/kmdb/models/ignored_user.rb +20 -0
  40. data/lib/kmdb/models/json_file.rb +56 -0
  41. data/lib/kmdb/models/key.rb +28 -0
  42. data/lib/kmdb/models/property.rb +44 -0
  43. data/lib/kmdb/models/s3_object.rb +54 -0
  44. data/lib/kmdb/models/user.rb +53 -0
  45. data/lib/kmdb/models/whitelisted_event.rb +20 -0
  46. data/lib/kmdb/parser.rb +4 -4
  47. data/lib/kmdb/redis.rb +17 -0
  48. data/lib/kmdb/resque.rb +38 -0
  49. data/lib/kmdb/s3_bucket.rb +33 -0
  50. data/lib/kmdb/services/partitioner.rb +65 -0
  51. data/lib/kmdb/version.rb +1 -1
  52. data/lib/kmdb.rb +31 -6
  53. metadata +236 -186
  54. data/README.markdown +0 -91
  55. data/bin/km_db_import +0 -36
  56. data/lib/kmdb/custom_record.rb +0 -54
  57. data/lib/kmdb/dumpfile.rb +0 -23
  58. data/lib/kmdb/event.rb +0 -39
  59. data/lib/kmdb/has_properties.rb +0 -33
  60. data/lib/kmdb/key.rb +0 -56
  61. data/lib/kmdb/migration.rb +0 -63
  62. data/lib/kmdb/parallel_parser.rb +0 -85
  63. data/lib/kmdb/property.rb +0 -33
  64. data/lib/kmdb/user.rb +0 -83
@@ -0,0 +1,260 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDQzCCAqygAwIBAgIJAOd1tlfiGoEoMA0GCSqGSIb3DQEBBQUAMHUxCzAJBgNV
3
+ BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdTZWF0dGxlMRMw
4
+ EQYDVQQKEwpBbWF6b24uY29tMQwwCgYDVQQLEwNSRFMxHDAaBgNVBAMTE2F3cy5h
5
+ bWF6b24uY29tL3Jkcy8wHhcNMTAwNDA1MjI0NDMxWhcNMTUwNDA0MjI0NDMxWjB1
6
+ MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHU2Vh
7
+ dHRsZTETMBEGA1UEChMKQW1hem9uLmNvbTEMMAoGA1UECxMDUkRTMRwwGgYDVQQD
8
+ ExNhd3MuYW1hem9uLmNvbS9yZHMvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
9
+ gQDKhXGU7tizxUR5WaFoMTFcxNxa05PEjZaIOEN5ctkWrqYSRov0/nOMoZjqk8bC
10
+ med9vPFoQGD0OTakPs0jVe3wwmR735hyVwmKIPPsGlaBYj1O6llIpZeQVyupNx56
11
+ UzqtiLaDzh1KcmfqP3qP2dInzBfJQKjiRudo1FWnpPt33QIDAQABo4HaMIHXMB0G
12
+ A1UdDgQWBBT/H3x+cqSkR/ePSIinPtc4yWKe3DCBpwYDVR0jBIGfMIGcgBT/H3x+
13
+ cqSkR/ePSIinPtc4yWKe3KF5pHcwdTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh
14
+ c2hpbmd0b24xEDAOBgNVBAcTB1NlYXR0bGUxEzARBgNVBAoTCkFtYXpvbi5jb20x
15
+ DDAKBgNVBAsTA1JEUzEcMBoGA1UEAxMTYXdzLmFtYXpvbi5jb20vcmRzL4IJAOd1
16
+ tlfiGoEoMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAvguZy/BDT66x
17
+ GfgnJlyQwnFSeVLQm9u/FIvz4huGjbq9dqnD6h/Gm56QPFdyMEyDiZWaqY6V08lY
18
+ LTBNb4kcIc9/6pc0/ojKciP5QJRm6OiZ4vgG05nF4fYjhU7WClUx7cxq1fKjNc2J
19
+ UCmmYqgiVkAGWRETVo+byOSDZ4swb10=
20
+ -----END CERTIFICATE-----
21
+ -----BEGIN CERTIFICATE-----
22
+ MIID9DCCAtygAwIBAgIBQjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx
23
+ EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM
24
+ GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx
25
+ GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUwOTExMzFaFw0y
26
+ MDAzMDUwOTExMzFaMIGKMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv
27
+ bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl
28
+ cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEbMBkGA1UEAwwSQW1hem9uIFJE
29
+ UyBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuD8nrZ8V
30
+ u+VA8yVlUipCZIKPTDcOILYpUe8Tct0YeQQr0uyl018StdBsa3CjBgvwpDRq1HgF
31
+ Ji2N3+39+shCNspQeE6aYU+BHXhKhIIStt3r7gl/4NqYiDDMWKHxHq0nsGDFfArf
32
+ AOcjZdJagOMqb3fF46flc8k2E7THTm9Sz4L7RY1WdABMuurpICLFE3oHcGdapOb9
33
+ T53pQR+xpHW9atkcf3pf7gbO0rlKVSIoUenBlZipUlp1VZl/OD/E+TtRhDDNdI2J
34
+ P/DSMM3aEsq6ZQkfbz/Ilml+Lx3tJYXUDmp+ZjzMPLk/+3beT8EhrwtcG3VPpvwp
35
+ BIOqsqVVTvw/CwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
36
+ AwEB/zAdBgNVHQ4EFgQUTgLurD72FchM7Sz1BcGPnIQISYMwHwYDVR0jBBgwFoAU
37
+ TgLurD72FchM7Sz1BcGPnIQISYMwDQYJKoZIhvcNAQEFBQADggEBAHZcgIio8pAm
38
+ MjHD5cl6wKjXxScXKtXygWH2BoDMYBJF9yfyKO2jEFxYKbHePpnXB1R04zJSWAw5
39
+ 2EUuDI1pSBh9BA82/5PkuNlNeSTB3dXDD2PEPdzVWbSKvUB8ZdooV+2vngL0Zm4r
40
+ 47QPyd18yPHrRIbtBtHR/6CwKevLZ394zgExqhnekYKIqqEX41xsUV0Gm6x4vpjf
41
+ 2u6O/+YE2U+qyyxHE5Wd5oqde0oo9UUpFETJPVb6Q2cEeQib8PBAyi0i6KnF+kIV
42
+ A9dY7IHSubtCK/i8wxMVqfd5GtbA8mmpeJFwnDvm9rBEsHybl08qlax9syEwsUYr
43
+ /40NawZfTUU=
44
+ -----END CERTIFICATE-----
45
+ -----BEGIN CERTIFICATE-----
46
+ MIIEATCCAumgAwIBAgIBRDANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx
47
+ EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM
48
+ GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx
49
+ GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMjAzMDZaFw0y
50
+ MDAzMDUyMjAzMDZaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv
51
+ bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl
52
+ cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1hem9uIFJE
53
+ UyBhcC1ub3J0aGVhc3QtMSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
54
+ ggEBAMmM2B4PfTXCZjbZMWiDPyxvk/eeNwIRJAhfzesiGUiLozX6CRy3rwC1ZOPV
55
+ AcQf0LB+O8wY88C/cV+d4Q2nBDmnk+Vx7o2MyMh343r5rR3Na+4izd89tkQVt0WW
56
+ vO21KRH5i8EuBjinboOwAwu6IJ+HyiQiM0VjgjrmEr/YzFPL8MgHD/YUHehqjACn
57
+ C0+B7/gu7W4qJzBL2DOf7ub2qszGtwPE+qQzkCRDwE1A4AJmVE++/FLH2Zx78Egg
58
+ fV1sUxPtYgjGH76VyyO6GNKM6rAUMD/q5mnPASQVIXgKbupr618bnH+SWHFjBqZq
59
+ HvDGPMtiiWII41EmGUypyt5AbysCAwEAAaNmMGQwDgYDVR0PAQH/BAQDAgEGMBIG
60
+ A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFIiKM0Q6n1K4EmLxs3ZXxINbwEwR
61
+ MB8GA1UdIwQYMBaAFE4C7qw+9hXITO0s9QXBj5yECEmDMA0GCSqGSIb3DQEBBQUA
62
+ A4IBAQBezGbE9Rw/k2e25iGjj5n8r+M3dlye8ORfCE/dijHtxqAKasXHgKX8I9Tw
63
+ JkBiGWiuzqn7gO5MJ0nMMro1+gq29qjZnYX1pDHPgsRjUX8R+juRhgJ3JSHijRbf
64
+ 4qNJrnwga7pj94MhcLq9u0f6dxH6dXbyMv21T4TZMTmcFduf1KgaiVx1PEyJjC6r
65
+ M+Ru+A0eM+jJ7uCjUoZKcpX8xkj4nmSnz9NMPog3wdOSB9cAW7XIc5mHa656wr7I
66
+ WJxVcYNHTXIjCcng2zMKd1aCcl2KSFfy56sRfT7J5Wp69QSr+jq8KM55gw8uqAwi
67
+ VPrXn2899T1rcTtFYFP16WXjGuc0
68
+ -----END CERTIFICATE-----
69
+ -----BEGIN CERTIFICATE-----
70
+ MIIEATCCAumgAwIBAgIBRTANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx
71
+ EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM
72
+ GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx
73
+ GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMjAzMTlaFw0y
74
+ MDAzMDUyMjAzMTlaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv
75
+ bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl
76
+ cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1hem9uIFJE
77
+ UyBhcC1zb3V0aGVhc3QtMSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
78
+ ggEBANaXElmSEYt/UtxHFsARFhSUahTf1KNJzR0Dmay6hqOXQuRVbKRwPd19u5vx
79
+ DdF1sLT7D69IK3VDnUiQScaCv2Dpu9foZt+rLx+cpx1qiQd1UHrvqq8xPzQOqCdC
80
+ RFStq6yVYZ69yfpfoI67AjclMOjl2Vph3ftVnqP0IgVKZdzeC7fd+umGgR9xY0Qr
81
+ Ubhd/lWdsbNvzK3f1TPWcfIKQnpvSt85PIEDJir6/nuJUKMtmJRwTymJf0i+JZ4x
82
+ 7dJa341p2kHKcHMgOPW7nJQklGBA70ytjUV6/qebS3yIugr/28mwReflg3TJzVDl
83
+ EOvi6pqbqNbkMuEwGDCmEQIVqgkCAwEAAaNmMGQwDgYDVR0PAQH/BAQDAgEGMBIG
84
+ A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAu93/4k5xbWOsgdCdn+/KdiRuit
85
+ MB8GA1UdIwQYMBaAFE4C7qw+9hXITO0s9QXBj5yECEmDMA0GCSqGSIb3DQEBBQUA
86
+ A4IBAQBlcjSyscpPjf5+MgzMuAsCxByqUt+WFspwcMCpwdaBeHOPSQrXNqX2Sk6P
87
+ kth6oCivA64trWo8tFMvPYlUA1FYVD5WpN0kCK+P5pD4KHlaDsXhuhClJzp/OP8t
88
+ pOyUr5109RHLxqoKB5J5m1XA7rgcFjnMxwBSWFe3/4uMk/+4T53YfCVXuc6QV3i7
89
+ I/2LAJwFf//pTtt6fZenYfCsahnr2nvrNRNyAxcfvGZ/4Opn/mJtR6R/AjvQZHiR
90
+ bkRNKF2GW0ueK5W4FkZVZVhhX9xh1Aj2Ollb+lbOqADaVj+AT3PoJPZ3MPQHKCXm
91
+ xwG0LOLlRr/TfD6li1AfOVTAJXv9
92
+ -----END CERTIFICATE-----
93
+ -----BEGIN CERTIFICATE-----
94
+ MIIEATCCAumgAwIBAgIBRjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx
95
+ EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM
96
+ GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx
97
+ GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMjAzMjRaFw0y
98
+ MDAzMDUyMjAzMjRaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv
99
+ bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl
100
+ cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1hem9uIFJE
101
+ UyBhcC1zb3V0aGVhc3QtMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
102
+ ggEBAJqBAJutz69hFOh3BtLHZTbwE8eejGGKayn9hu98YMDPzWzGXWCmW+ZYWELA
103
+ cY3cNWNF8K4FqKXFr2ssorBYim1UtYFX8yhydT2hMD5zgQ2sCGUpuidijuPA6zaq
104
+ Z3tdhVR94f0q8mpwpv2zqR9PcqaGDx2VR1x773FupRPRo7mEW1vC3IptHCQlP/zE
105
+ 7jQiLl28bDIH2567xg7e7E9WnZToRnhlYdTaDaJsHTzi5mwILi4cihSok7Shv/ME
106
+ hnukvxeSPUpaVtFaBhfBqq055ePq9I+Ns4KGreTKMhU0O9fkkaBaBmPaFgmeX/XO
107
+ n2AX7gMouo3mtv34iDTZ0h6YCGkCAwEAAaNmMGQwDgYDVR0PAQH/BAQDAgEGMBIG
108
+ A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFIlQnY0KHYWn1jYumSdJYfwj/Nfw
109
+ MB8GA1UdIwQYMBaAFE4C7qw+9hXITO0s9QXBj5yECEmDMA0GCSqGSIb3DQEBBQUA
110
+ A4IBAQA0wVU6/l41cTzHc4azc4CDYY2Wd90DFWiH9C/mw0SgToYfCJ/5Cfi0NT/Y
111
+ PRnk3GchychCJgoPA/k9d0//IhYEAIiIDjyFVgjbTkKV3sh4RbdldKVOUB9kumz/
112
+ ZpShplsGt3z4QQiVnKfrAgqxWDjR0I0pQKkxXa6Sjkicos9LQxVtJ0XA4ieG1E7z
113
+ zJr+6t80wmzxvkInSaWP3xNJK9azVRTrgQZQlvkbpDbExl4mNTG66VD3bAp6t3Wa
114
+ B49//uDdfZmPkqqbX+hsxp160OH0rxJppwO3Bh869PkDnaPEd/Pxw7PawC+li0gi
115
+ NRV8iCEx85aFxcyOhqn0WZOasxee
116
+ -----END CERTIFICATE-----
117
+ -----BEGIN CERTIFICATE-----
118
+ MIID/zCCAuegAwIBAgIBRzANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx
119
+ EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM
120
+ GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx
121
+ GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMjAzMzFaFw0y
122
+ MDAzMDUyMjAzMzFaMIGSMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv
123
+ bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl
124
+ cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEjMCEGA1UEAwwaQW1hem9uIFJE
125
+ UyBldS1jZW50cmFsLTEgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
126
+ AQDFtP2dhSLuaPOI4ZrrPWsK4OY9ocQBp3yApH1KJYmI9wpQKZG/KCH2E6Oo7JAw
127
+ QORU519r033T+FO2Z7pFPlmz1yrxGXyHpJs8ySx3Yo5S8ncDCdZJCLmtPiq/hahg
128
+ 5/0ffexMFUCQaYicFZsrJ/cStdxUV+tSw2JQLD7UxS9J97LQWUPyyG+ZrjYVTVq+
129
+ zudnFmNSe4QoecXMhAFTGJFQXxP7nhSL9Ao5FGgdXy7/JWeWdQIAj8ku6cBDKPa6
130
+ Y6kP+ak+In+Lye8z9qsCD/afUozfWjPR2aA4JoIZVF8dNRShIMo8l0XfgfM2q0+n
131
+ ApZWZ+BjhIO5XuoUgHS3D2YFAgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNV
132
+ HRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBRm4GsWIA/M6q+tK8WGHWDGh2gcyTAf
133
+ BgNVHSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQUFAAOC
134
+ AQEAHpMmeVQNqcxgfQdbDIi5UIy+E7zZykmtAygN1XQrvga9nXTis4kOTN6g5/+g
135
+ HCx7jIXeNJzAbvg8XFqBN84Quqgpl/tQkbpco9Jh1HDs558D5NnZQxNqH5qXQ3Mm
136
+ uPgCw0pYcPOa7bhs07i+MdVwPBsX27CFDtsgAIru8HvKxY1oTZrWnyIRo93tt/pk
137
+ WuItVMVHjaQZVfTCow0aDUbte6Vlw82KjUFq+n2NMSCJDiDKsDDHT6BJc4AJHIq3
138
+ /4Z52MSC9KMr0yAaaoWfW/yMEj9LliQauAgwVjArF4q78rxpfKTG9Rfd8U1BZANP
139
+ 7FrFMN0ThjfA1IvmOYcgskY5bQ==
140
+ -----END CERTIFICATE-----
141
+ -----BEGIN CERTIFICATE-----
142
+ MIID/DCCAuSgAwIBAgIBSDANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx
143
+ EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM
144
+ GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx
145
+ GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMjAzMzVaFw0y
146
+ MDAzMDUyMjAzMzVaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv
147
+ bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl
148
+ cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEgMB4GA1UEAwwXQW1hem9uIFJE
149
+ UyBldS13ZXN0LTEgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx
150
+ PdbqQ0HKRj79Pmocxvjc+P6i4Ux24kgFIl+ckiir1vzkmesc3a58gjrMlCksEObt
151
+ Yihs5IhzEq1ePT0gbfS9GYFp34Uj/MtPwlrfCBWG4d2TcrsKRHr1/EXUYhWqmdrb
152
+ RhX8XqoRhVkbF/auzFSBhTzcGGvZpQ2KIaxRcQfcXlMVhj/pxxAjh8U4F350Fb0h
153
+ nX1jw4/KvEreBL0Xb2lnlGTkwVxaKGSgXEnOgIyOFdOQc61vdome0+eeZsP4jqeR
154
+ TGYJA9izJsRbe2YJxHuazD+548hsPlM3vFzKKEVURCha466rAaYAHy3rKur3HYQx
155
+ Yt+SoKcEz9PXuSGj96ejAgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB
156
+ Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBTebg//h2oeXbZjQ4uuoiuLYzuiPDAfBgNV
157
+ HSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQUFAAOCAQEA
158
+ TikPaGeZasTPw+4RBemlsyPAjtFFQLo7ddaFdORLgdEysVf8aBqndvbA6MT/v4lj
159
+ GtEtUdF59ZcbWOrVm+fBZ2h/jYJ59dYF/xzb09nyRbdMSzB9+mkSsnOMqluq5y8o
160
+ DY/PfP2vGhEg/2ZncRC7nlQU1Dm8F4lFWEiQ2fi7O1cW852Vmbq61RIfcYsH/9Ma
161
+ kpgk10VZ75b8m3UhmpZ/2uRY+JEHImH5WpcTJ7wNiPNJsciZMznGtrgOnPzYco8L
162
+ cDleOASIZifNMQi9PKOJKvi0ITz0B/imr8KBsW0YjZVJ54HMa7W1lwugSM7aMAs+
163
+ E3Sd5lS+SHwWaOCHwhOEVA==
164
+ -----END CERTIFICATE-----
165
+ -----BEGIN CERTIFICATE-----
166
+ MIID/DCCAuSgAwIBAgIBSTANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx
167
+ EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM
168
+ GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx
169
+ GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMjAzNDBaFw0y
170
+ MDAzMDUyMjAzNDBaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv
171
+ bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl
172
+ cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEgMB4GA1UEAwwXQW1hem9uIFJE
173
+ UyBzYS1lYXN0LTEgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCU
174
+ X4OBnQ5xA6TLJAiFEI6l7bUWjoVJBa/VbMdCCSs2i2dOKmqUaXu2ix2zcPILj3lZ
175
+ GMk3d/2zvTK/cKhcFrewHUBamTeVHdEmynhMQamqNmkM4ptYzFcvEUw1TGxHT4pV
176
+ Q6gSN7+/AJewQvyHexHo8D0+LDN0/Wa9mRm4ixCYH2CyYYJNKaZt9+EZfNu+PPS4
177
+ 8iB0TWH0DgQkbWMBfCRgolLLitAZklZ4dvdlEBS7evN1/7ttBxUK6SvkeeSx3zBl
178
+ ww3BlXqc3bvTQL0A+RRysaVyFbvtp9domFaDKZCpMmDFAN/ntx215xmQdrSt+K3F
179
+ cXdGQYHx5q410CAclGnbAgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB
180
+ Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBT6iVWnm/uakS+tEX2mzIfw+8JL0zAfBgNV
181
+ HSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQUFAAOCAQEA
182
+ FmDD+QuDklXn2EgShwQxV13+txPRuVdOSrutHhoCgMwFWCMtPPtBAKs6KPY7Guvw
183
+ DpJoZSehDiOfsgMirjOWjvfkeWSNvKfjWTVneX7pZD9W5WPnsDBvTbCGezm+v87z
184
+ b+ZM2ZMo98m/wkMcIEAgdSKilR2fuw8rLkAjhYFfs0A7tDgZ9noKwgHvoE4dsrI0
185
+ KZYco6DlP/brASfHTPa2puBLN9McK3v+h0JaSqqm5Ro2Bh56tZkQh8AWy/miuDuK
186
+ 3+hNEVdxosxlkM1TPa1DGj0EzzK0yoeerXuH2HX7LlCrrxf6/wdKnjR12PMrLQ4A
187
+ pCqkcWw894z6bV9MAvKe6A==
188
+ -----END CERTIFICATE-----
189
+ -----BEGIN CERTIFICATE-----
190
+ MIID/DCCAuSgAwIBAgIBQzANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx
191
+ EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM
192
+ GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx
193
+ GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMTU0MDRaFw0y
194
+ MDAzMDUyMTU0MDRaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv
195
+ bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl
196
+ cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEgMB4GA1UEAwwXQW1hem9uIFJE
197
+ UyB1cy1lYXN0LTEgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDI
198
+ UIuwh8NusKHk1SqPXcP7OqxY3S/M2ZyQWD3w7Bfihpyyy/fc1w0/suIpX3kbMhAV
199
+ 2ESwged2/2zSx4pVnjp/493r4luhSqQYzru78TuPt9bhJIJ51WXunZW2SWkisSaf
200
+ USYUzVN9ezR/bjXTumSUQaLIouJt3OHLX49s+3NAbUyOI8EdvgBQWD68H1epsC0n
201
+ CI5s+pIktyOZ59c4DCDLQcXErQ+tNbDC++oct1ANd/q8p9URonYwGCGOBy7sbCYq
202
+ 9eVHh1Iy2M+SNXddVOGw5EuruvHoCIQyOz5Lz4zSuZA9dRbrfztNOpezCNYu6NKM
203
+ n+hzcvdiyxv77uNm8EaxAgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB
204
+ Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBQSQG3TmMe6Sa3KufaPBa72v4QFDzAfBgNV
205
+ HSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQUFAAOCAQEA
206
+ L/mOZfB3187xTmjOHMqN2G2oSKHBKiQLM9uv8+97qT+XR+TVsBT6b3yoPpMAGhHA
207
+ Pc7nxAF5gPpuzatx0OTLPcmYucFmfqT/1qA5WlgCnMNtczyNMH97lKFTNV7Njtek
208
+ jWEzAEQSyEWrkNpNlC4j6kMYyPzVXQeXUeZTgJ9FNnVZqmvfjip2N22tawMjrCn5
209
+ 7KN/zN65EwY2oO9XsaTwwWmBu3NrDdMbzJnbxoWcFWj4RBwanR1XjQOVNhDwmCOl
210
+ /1Et13b8CPyj69PC8BOVU6cfTSx8WUVy0qvYOKHNY9Bqa5BDnIL3IVmUkeTlM1mt
211
+ enRpyBj+Bk9rh/ICdiRKmA==
212
+ -----END CERTIFICATE-----
213
+ -----BEGIN CERTIFICATE-----
214
+ MIID/DCCAuSgAwIBAgIBSjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx
215
+ EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM
216
+ GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx
217
+ GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMjAzNDVaFw0y
218
+ MDAzMDUyMjAzNDVaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv
219
+ bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl
220
+ cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEgMB4GA1UEAwwXQW1hem9uIFJE
221
+ UyB1cy13ZXN0LTEgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDE
222
+ Dhw+uw/ycaiIhhyu2pXFRimq0DlB8cNtIe8hdqndH8TV/TFrljNgR8QdzOgZtZ9C
223
+ zzQ2GRpInN/qJF6slEd6wO+6TaDBQkPY+07TXNt52POFUhdVkhJXHpE2BS7Xn6J7
224
+ 7RFAOeG1IZmc2DDt+sR1BgXzUqHslQGfFYNS0/MBO4P+ya6W7IhruB1qfa4HiYQS
225
+ dbe4MvGWnv0UzwAqdR7OF8+8/5c58YXZIXCO9riYF2ql6KNSL5cyDPcYK5VK0+Q9
226
+ VI6vuJHSMYcF7wLePw8jtBktqAFE/wbdZiIHhZvNyiNWPPNTGUmQbaJ+TzQEHDs5
227
+ 8en+/W7JKnPyBOkxxENbAgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB
228
+ Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBS0nw/tFR9bCjgqWTPJkyy4oOD8bzAfBgNV
229
+ HSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQUFAAOCAQEA
230
+ CXGAY3feAak6lHdqj6+YWjy6yyUnLK37bRxZDsyDVXrPRQaXRzPTzx79jvDwEb/H
231
+ Q/bdQ7zQRWqJcbivQlwhuPJ4kWPUZgSt3JUUuqkMsDzsvj/bwIjlrEFDOdHGh0mi
232
+ eVIngFEjUXjMh+5aHPEF9BlQnB8LfVtKj18e15UDTXFa+xJPFxUR7wDzCfo4WI1m
233
+ sUMG4q1FkGAZgsoyFPZfF8IVvgCuGdR8z30VWKklFxttlK0eGLlPAyIO0CQxPQlo
234
+ saNJrHf4tLOgZIWk+LpDhNd9Et5EzvJ3aURUsKY4pISPPF5WdvM9OE59bERwUErd
235
+ nuOuQWQeeadMceZnauRzJQ==
236
+ -----END CERTIFICATE-----
237
+ -----BEGIN CERTIFICATE-----
238
+ MIID/DCCAuSgAwIBAgIBSzANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx
239
+ EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM
240
+ GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx
241
+ GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMjAzNTBaFw0y
242
+ MDAzMDUyMjAzNTBaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv
243
+ bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl
244
+ cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEgMB4GA1UEAwwXQW1hem9uIFJE
245
+ UyB1cy13ZXN0LTIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDM
246
+ H58SR48U6jyERC1vYTnub34smf5EQVXyzaTmspWGWGzT31NLNZGSDFaa7yef9kdO
247
+ mzJsgebR5tXq6LdwlIoWkKYQ7ycUaadtVKVYdI40QcI3cHn0qLFlg2iBXmWp/B+i
248
+ Z34VuVlCh31Uj5WmhaBoz8t/GRqh1V/aCsf3Wc6jCezH3QfuCjBpzxdOOHN6Ie2v
249
+ xX09O5qmZTvMoRBAvPkxdaPg/Mi7fxueWTbEVk78kuFbF1jHYw8U1BLILIAhcqlq
250
+ x4u8nl73t3O3l/soNUcIwUDK0/S+Kfqhwn9yQyPlhb4Wy3pfnZLJdkyHldktnQav
251
+ 9TB9u7KH5Lk0aAYslMLxAgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB
252
+ Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBT8roM4lRnlFHWMPWRz0zkwFZog1jAfBgNV
253
+ HSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQUFAAOCAQEA
254
+ JwrxwgwmPtcdaU7O7WDdYa4hprpOMamI49NDzmE0s10oGrqmLwZygcWU0jT+fJ+Y
255
+ pJe1w0CVfKaeLYNsOBVW3X4ZPmffYfWBheZiaiEflq/P6t7/Eg81gaKYnZ/x1Dfa
256
+ sUYkzPvCkXe9wEz5zdUTOCptDt89rBR9CstL9vE7WYUgiVVmBJffWbHQLtfjv6OF
257
+ NMb0QME981kGRzc2WhgP71YS2hHd1kXtsoYP1yTu4vThSKsoN4bkiHsaC1cRkLoy
258
+ 0fFA4wpB3WloMEvCDaUvvH1LZlBXTNlwi9KtcwD4tDxkkBt4tQczKLGpQ/nF/W9n
259
+ 8YDWk3IIc1sd0bkZqoau2Q==
260
+ -----END CERTIFICATE-----
data/config.ru ADDED
@@ -0,0 +1,8 @@
1
+ require 'resque/server'
2
+ require 'kmdb/resque'
3
+
4
+ KMDB::Resque.configure
5
+
6
+ run Rack::URLMap.new \
7
+ '/resque' => Resque::Server.new
8
+
data/km-db.gemspec CHANGED
@@ -5,25 +5,25 @@ Gem::Specification.new do |s|
5
5
  s.name = "km-db"
6
6
  s.version = KMDB::VERSION
7
7
  s.platform = Gem::Platform::RUBY
8
- s.authors = ["HouseTrip"]
9
- s.email = ["jtl@housetrip.com"]
10
- s.homepage = "https://github.com/housetrip/km-db"
11
- s.summary = "Process KISSmetrics data dumps"
12
- s.description = "Process KISSmetrics data dumps"
8
+ s.authors = ['Julien Letessier']
9
+ s.email = ['julien.letessier@gmail.com']
10
+ s.homepage = 'https://github.com/housetrip/km-db'
11
+ s.summary = 'Process KISSmetrics data dumps'
13
12
 
14
- s.required_rubygems_version = ">= 1.3.6"
15
-
16
- s.add_development_dependency "bundler", ">= 1.0.0"
17
- s.add_development_dependency "rspec", "~> 2.4.0"
18
- s.add_development_dependency "rake"
19
- s.add_development_dependency "json"
20
- s.add_development_dependency "sqlite3-ruby"
13
+ s.add_development_dependency 'bundler'
14
+ s.add_development_dependency 'rspec', '~> 2.4.0'
15
+ s.add_development_dependency 'rake'
16
+ s.add_development_dependency 'pry'
21
17
 
22
- s.add_dependency "yajl-ruby"
23
- s.add_dependency "progressbar"
24
- s.add_dependency "parallel"
25
- s.add_dependency "andand"
26
- s.add_dependency "activerecord", "~> 2.3.12"
18
+ s.add_dependency 'oj'
19
+ s.add_dependency 'progressbar'
20
+ s.add_dependency 'andand'
21
+ s.add_dependency 'activerecord', '~> 4.1'
22
+ s.add_dependency 'resque'
23
+ s.add_dependency 'resque-lock'
24
+ s.add_dependency 'foreman'
25
+ s.add_dependency 'fog'
26
+ s.add_dependency 'mysql2'
27
27
 
28
28
  s.files = `git ls-files`.split("\n")
29
29
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -2,12 +2,12 @@ module KMDB
2
2
  module BelongsToUser
3
3
  def self.included(mod)
4
4
  mod.class_eval do
5
- belongs_to :user, :class_name => 'KMDB::User'
5
+ belongs_to :user, class_name: 'KMDB::User'
6
6
  validates_presence_of :user
7
7
 
8
- named_scope :user_is, lambda { |user|
8
+ scope :user_is, lambda { |user|
9
9
  user.kind_of?(User) or raise TypeError.new("Not a kind of User")
10
- { :conditions => { :user_id => user.id } }
10
+ where(user_id: user.id)
11
11
  }
12
12
  end
13
13
  end
@@ -0,0 +1,35 @@
1
+ =begin
2
+
3
+ KMDB::HasProperties --
4
+
5
+ Trait shared by Event and User.
6
+
7
+ =end
8
+ require 'kmdb/models/property'
9
+ require 'kmdb/models/key'
10
+
11
+ module KMDB
12
+ module HasProperties
13
+ def self.included(mod)
14
+ mod.class_eval do
15
+ has_many :properties, class_name: 'KMDB::Property'
16
+
17
+ # scope :with_properties, lambda { |*props|
18
+ # direction = props.delete(:exclude_missing) ? 'INNER' : 'LEFT'
19
+ # prop_table = Property.table_name
20
+ # selects = ["`#{table_name}`.*"]
21
+ # joins = []
22
+ # props.each_with_index { |prop,k|
23
+ # temp_name = "#{prop_table}_#{k}"
24
+ # selects << "`#{temp_name}`.`value` AS `#{prop.split.join('_')}`"
25
+ # joins << sanitize_sql_array([%Q{
26
+ # #{direction} JOIN `properties` AS `#{temp_name}`
27
+ # ON `#{table_name}`.id = `#{temp_name}`.event_id
28
+ # AND `#{temp_name}`.`key` = ?}, KMDB::Key.get(prop)])
29
+ # }
30
+ # { select: selects.join(', '), joins: joins.join("\n") }
31
+ # }
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,32 @@
1
+ require 'kmdb'
2
+ require 'kmdb/models/dumpfile'
3
+ require 'kmdb/models/json_file'
4
+ require 'kmdb/jobs/locked'
5
+ require 'kmdb/jobs/parse_file'
6
+ require 'kmdb/resque'
7
+
8
+ module KMDB
9
+ module Jobs
10
+ # Detects a batch up new revision files in S3 and adds Dumpfiles for them.
11
+ class FindFiles < Locked
12
+ @queue = :low
13
+
14
+ def self.perform
15
+ new.work
16
+ end
17
+
18
+ def work
19
+ lookahead = Integer(ENV.fetch('KMDB_REVISION_LOOKAHEAD', 10))
20
+ start_at = Dumpfile.maximum(:revision) || Integer(ENV.fetch('KMDB_MIN_REVISION', 1))
21
+
22
+ start_at.upto(start_at + lookahead).map do |revision|
23
+ json_file = JsonFile.new(revision)
24
+ next unless json_file.exist?
25
+ Resque.enqueue(ParseFile, json_file.revision)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+
@@ -0,0 +1,37 @@
1
+ require 'kmdb'
2
+ require 'kmdb/resque'
3
+ require 'pathname'
4
+ require 'kmdb/jobs/locked'
5
+ require 'kmdb/jobs/parse_file'
6
+ require 'kmdb/models/dumpfile'
7
+
8
+ module KMDB
9
+ module Jobs
10
+ # Lists known dump files, queues parse jobs for each
11
+ class ListFiles < Locked
12
+ @queue = :low
13
+
14
+ def self.perform
15
+ new.work
16
+ end
17
+
18
+ def work
19
+ Dumpfile.find_each do |meta|
20
+ next if meta.complete?
21
+ Resque.enqueue(ParseFile, meta.revision)
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def _list_jsons_in_directory(directory)
28
+ input_fns = []
29
+ directory.find do |input_pn|
30
+ input_pn.extname == '.json' or next
31
+ input_fns << input_pn
32
+ end
33
+ input_fns.sort
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,10 @@
1
+ require 'kmdb'
2
+ require 'resque/plugins/lock'
3
+
4
+ module KMDB
5
+ module Jobs
6
+ class Locked
7
+ extend ::Resque::Plugins::Lock
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,109 @@
1
+ require 'kmdb'
2
+ require 'pathname'
3
+ require 'kmdb/models/dumpfile'
4
+ require 'kmdb/models/event_batch'
5
+ require 'kmdb/jobs/locked'
6
+ require 'kmdb/jobs/record_batch'
7
+ require 'kmdb/resque'
8
+ require 'oj'
9
+
10
+ module KMDB
11
+ module Jobs
12
+ # Reads a file from disk,
13
+ # queues jobs for chunks of events.
14
+ class ParseFile < Locked
15
+ @queue = :low
16
+
17
+ def self.perform(id)
18
+ new(JsonFile.new(id)).work
19
+ end
20
+
21
+ def initialize(file)
22
+ @file = file
23
+ end
24
+
25
+ def work
26
+ current_batch = []
27
+ current_stamp = nil
28
+
29
+ _each_event_in_file(@file) do |event|
30
+ if event.nil?
31
+ _save_batch(current_batch)
32
+ true
33
+ elsif current_batch.length > _batch_size && event['_t'] != current_stamp
34
+ _save_batch(current_batch)
35
+ current_batch << event
36
+ true
37
+ else
38
+ current_batch << event
39
+ false
40
+ end
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def _batch_size
47
+ Integer(ENV.fetch('KMDB_BATCH_SIZE', 100))
48
+ end
49
+
50
+ def _save_batch(batch)
51
+ saved_batch = EventBatch.new(batch).save!
52
+ Resque.enqueue(Jobs::RecordBatch, saved_batch.id)
53
+ batch.clear
54
+ end
55
+
56
+ # yields event hashes; yields nil once after the last event.
57
+ # notes down progress in Dumpfile when the yield returns true.
58
+ def _each_event_in_file(file)
59
+ file.open do |input|
60
+ meta = file.metadata
61
+ log "Parsing file #{file.revision} from offset #{meta.offset}"
62
+ input.seek(meta.offset)
63
+ while true
64
+ line = input.gets
65
+ if yield _parse_event(line)
66
+ meta.set(input.tell)
67
+ end
68
+ break if line.nil?
69
+ end
70
+ end
71
+ end
72
+
73
+ # text line in, event hash out
74
+ def _parse_event(text)
75
+ return if text.nil?
76
+ text = text.force_encoding('UTF-8').scrub
77
+
78
+ # filter strange utf-8 encoding/escaping found in KM dumps
79
+ if text =~ /(\\[0-9]{3})+/
80
+ begin
81
+ text = eval("%Q(#{text})")
82
+ rescue SyntaxError => e
83
+ log "Syntax error in: #{text}"
84
+ raise e if @abort_on_error
85
+ end
86
+ end
87
+
88
+ begin
89
+ data = Oj.load(text)
90
+ rescue Oj::ParseError => e
91
+ log "Warning, JSON parse error in: #{text}"
92
+ raise e if @abort_on_error
93
+ return
94
+ end
95
+
96
+ if data.nil?
97
+ log "Warning, JSON parse failed in: #{text}"
98
+ return
99
+ end
100
+
101
+ return data
102
+ end
103
+
104
+ def log(message)
105
+ $stderr.write("#{message}\n")
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,65 @@
1
+ require 'kmdb'
2
+ require 'kmdb/resque'
3
+ require 'kmdb/models/event_batch'
4
+ require 'kmdb/models/user'
5
+ require 'kmdb/models/alias'
6
+ require 'kmdb/models/event'
7
+ require 'kmdb/models/property'
8
+ require 'kmdb/models/global_uid'
9
+ require 'kmdb/models/ignored_user'
10
+ require 'kmdb/models/whitelisted_event'
11
+ require 'kmdb/jobs/locked'
12
+ require 'kmdb/jobs/unalias_user'
13
+
14
+ module KMDB
15
+ module Jobs
16
+ class RecordBatch < Locked
17
+ @queue = :high
18
+
19
+ def self.perform(id)
20
+ new(id).work
21
+ end
22
+
23
+ def initialize(id)
24
+ @batch = EventBatch.find(id)
25
+ raise ArgumentError.new('no such batch') if @batch.nil?
26
+ end
27
+
28
+ def work
29
+ event_sql = []
30
+ properties_sql = []
31
+
32
+ @batch.events.each do |event|
33
+ # reject non-whitelisted events
34
+ next unless event['_n'].nil? || WhitelistedEvent.include?(event['_n'])
35
+
36
+ # reject ignored users
37
+ next if IgnoredUser.include?(event['_p']) ||
38
+ IgnoredUser.include?(event['_p2'])
39
+
40
+ # store depending on event type
41
+ if event['_p2']
42
+ # ignore aliasing between "real" users
43
+ next if event['_p'] =~ /^\d+$/ && event['_p2'] =~ /^\d+$/
44
+ aliaz = Alias.record event['_p'], event['_p2'], event['_t']
45
+ Resque.enqueue(UnaliasUser, aliaz.name1, aliaz.name2)
46
+ elsif event['_n']
47
+ Event.sql_for(event) do |e,p|
48
+ event_sql << e
49
+ properties_sql << p
50
+ end
51
+ else
52
+ properties_sql << Property.sql_for(event)
53
+ end
54
+ end
55
+
56
+ KMDB.transaction do |c|
57
+ Event.mass_create(event_sql.compact)
58
+ Property.mass_create(properties_sql.compact)
59
+ end
60
+
61
+ @batch.delete
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,31 @@
1
+ require 'kmdb'
2
+ require 'kmdb/resque'
3
+ require 'kmdb/models/alias'
4
+ require 'kmdb/jobs/locked'
5
+ require 'kmdb/jobs/unalias_user'
6
+ require 'time'
7
+
8
+ module KMDB
9
+ module Jobs
10
+ # Processes recent unalias user events, again
11
+ # This copes with parallelism in the import process
12
+ class RedoUnaliasing < Locked
13
+ @queue = :low
14
+
15
+ def self.perform(date)
16
+ new(date).work
17
+ end
18
+
19
+ def initialize(date)
20
+ @date = Date.parse(date)
21
+ end
22
+
23
+ def work
24
+ Alias.where('t BETWEEN ? AND ?', @date, @date.next).find_each do |aliaz|
25
+ Resque.enqueue(UnaliasUser, aliaz.name1, aliaz.name2)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+