summary refs log tree commit diff
path: root/synapse/storage (follow)
Commit message (Expand)AuthorAgeFilesLines
* Send room name and first alias in notification poke.David Baker2015-01-151-0/+35
* Honour the 'rejected' return from push gatewaysDavid Baker2015-01-133-11/+25
* Merge branch 'develop' into pushersDavid Baker2015-01-1336-183/+294
|\
| * SYN-178: Fix off by one.Kegan Dougal2015-01-121-2/+6
| * Use time.time() instead of time.clock()Erik Johnston2015-01-061-4/+4
| * Only fetch the columns we need.Erik Johnston2015-01-061-1/+1
| * Add delta and bump DB versionErik Johnston2015-01-062-1/+17
| * Add index on transaction_id to sent_transcationsErik Johnston2015-01-062-4/+1
| * Actually time that functionErik Johnston2015-01-061-0/+1
| * Time how long calls to _get_destination_retry_timings takeErik Johnston2015-01-061-0/+3
| * Don't include None's in _get_events_txnErik Johnston2015-01-061-1/+3
| * Merge branch 'erikj-perf' of github.com:matrix-org/synapse into developErik Johnston2015-01-061-21/+49
| |\
| | * Name 'user_rooms_intersect' transactionErik Johnston2015-01-061-16/+18
| | * We don't need the full events for get_rooms_for_user_where_membership_isErik Johnston2015-01-061-5/+31
| * | Merge pull request #28 from matrix-org/erikj-perfMark Haines2015-01-064-103/+113
| |\|
| | * PEP8Erik Johnston2015-01-062-3/+4
| | * Remove debug linesErik Johnston2015-01-061-7/+0
| | * Don't do batching when getting events.Erik Johnston2015-01-061-35/+4
| | * Only fetch prev_content when a client is streaming/paginating. Use transactio...Erik Johnston2015-01-062-86/+92
| | * Temporarily turn off 'redacted_because' and 'prev_content' keysErik Johnston2015-01-061-0/+2
| | * More debug loggingErik Johnston2015-01-061-0/+4
| | * Add some debug loggingErik Johnston2015-01-061-0/+12
| | * ReformatErik Johnston2015-01-061-13/+14
| | * Add RoomMemberStore.get_users_in_room, so that we can get the list of joined ...Erik Johnston2015-01-061-0/+13
| | * Merge branch 'hotfixes-v0.6.0' of github.com:matrix-org/synapse into erikj-perfErik Johnston2014-12-191-4/+4
| | |\
| | * | Test some ideas that might help performance a bitErik Johnston2014-12-173-21/+30
| * | | Update copyright noticesMark Haines2015-01-0635-31/+87
| | |/ | |/|
| * | Look for name, topic in the event content rather than the event itself when p...Mark Haines2014-12-191-4/+4
| |/
| * Use _get_events_txn instead of _parse_events_txnErik Johnston2014-12-161-7/+1
| * Merge branch 'hotfixes-v0.5.4a' of github.com:matrix-org/synapse into release...Erik Johnston2014-12-161-8/+8
| |\
| | * Fix bug where we did not send the full auth chain to people that joined over ...Erik Johnston2014-12-161-8/+8
| * | Merge branch 'develop' of github.com:matrix-org/synapse into release-v0.6.0Erik Johnston2014-12-161-80/+0
| |\ \
| * | | Use is_outlier() so that we don't get AttributeErrorErik Johnston2014-12-161-3/+1
| * | | Don't assume an event existsErik Johnston2014-12-161-2/+4
* | | | Merge branch 'develop' into pushersDavid Baker2014-12-1812-243/+561
|\ \ \ \ | | |/ / | |/| |
| * | | Merge branch 'release-v0.6.0' into developMark Haines2014-12-162-2/+70
| |\| |
| | * | Fix upgrade script to run all the missing deltas.Erik Johnston2014-12-161-1/+57
| | * | Do run all deltas up to missing delta 10Erik Johnston2014-12-161-4/+4
| | * | Make failure to run appropraite upgrade scripts more helpful.Erik Johnston2014-12-161-0/+12
| | * | Bump database versionErik Johnston2014-12-161-1/+1
| * | | Remove send_message since nothing was calling it. Remove Snapshot because onl...Mark Haines2014-12-161-80/+0
| |/ /
| * | Update upgrade scriptErik Johnston2014-12-161-1/+1
| * | Persist internal_metadataErik Johnston2014-12-163-3/+10
| * | Kill off synapse.api.events.*Erik Johnston2014-12-161-10/+6
| * | Use frozenutilsErik Johnston2014-12-151-2/+1
| * | Fix bug where we ignored event_edge_hashes tableErik Johnston2014-12-153-7/+6
| * | Store json as UTF-8 and not bytesErik Johnston2014-12-121-1/+1
| * | PyflakesErik Johnston2014-12-121-1/+0
| * | Merge branch 'develop' of github.com:matrix-org/synapse into events_refactorErik Johnston2014-12-113-1/+202
| |\ \
| | * \ Merge branch 'develop' into media_repositoryMark Haines2014-12-105-3/+136
| | |\ \
| | * \ \ Merge branch 'develop' into media_repositoryMark Haines2014-12-106-20/+83
| | |\ \ \ | | | | |/ | | | |/|
| | * | | Get the code actually workingMark Haines2014-12-101-6/+8
| | * | | Thumbnail uploaded and cached imagesMark Haines2014-12-101-6/+6
| | * | | Add a method field to thumbnail storageMark Haines2014-12-052-7/+12
| | * | | Implement download support for media_repositoryMark Haines2014-12-041-3/+7
| | * | | Fix pyflakes and pep8 warningsMark Haines2014-12-021-2/+1
| | * | | Get uploads working with new media repoMark Haines2014-12-022-2/+11
| | * | | Write the upload portion of version 1 of the media repositoryMark Haines2014-12-022-0/+182
| * | | | Fix public room joining by making sure replaces_state never points to itself.Erik Johnston2014-12-111-2/+4
| * | | | Fix prev_contentErik Johnston2014-12-111-0/+6
| * | | | Fix redactions. Fix 'age' keyErik Johnston2014-12-111-24/+36
| * | | | Remove dead codeErik Johnston2014-12-101-25/+0
| * | | | Fix bug where we clobbered old state group valuesErik Johnston2014-12-102-2/+4
| * | | | Fix bug when uploading state with empty state_keyErik Johnston2014-12-102-1/+5
| * | | | Merge branch 'develop' of github.com:matrix-org/synapse into events_refactorErik Johnston2014-12-105-3/+136
| |\ \ \ \ | | | |_|/ | | |/| |
| | * | | Code style.Erik Johnston2014-12-101-21/+29
| | * | | squidge to 79 columns as per pep8Matthew Hodgson2014-12-101-6/+12
| | * | | fix a million stupid bugs and make it actually workMatthew Hodgson2014-12-081-11/+14
| | * | | add a write-through cache on the retry scheduleMatthew Hodgson2014-12-081-4/+15
| | * | | fix stupid syntax thinkosMatthew Hodgson2014-12-071-1/+1
| | * | | track replication destination health, and perform exponential back-off when s...Matthew Hodgson2014-12-075-3/+108
| | | |/ | | |/|
| * | | Try and figure out how and why signatures are being changed.Erik Johnston2014-12-101-10/+0
| * | | Change the way we implement get_events to be less suckyErik Johnston2014-12-092-36/+22
| * | | Remove unused importErik Johnston2014-12-081-1/+0
| * | | Various typos and bug fixes.Erik Johnston2014-12-081-3/+3
| * | | Start making more things use EventContext rather than event.*Erik Johnston2014-12-053-19/+25
| * | | Convert rest and handlers to use new event structureErik Johnston2014-12-041-1/+4
| * | | Begin converting things to use the new Event structureErik Johnston2014-12-041-0/+16
| * | | Merge branch 'develop' of github.com:matrix-org/synapse into events_refactorErik Johnston2014-12-031-1/+3
| |\| |
| * | | Store full JSON of events in dbErik Johnston2014-12-013-56/+50
* | | | schema version is now 10David Baker2014-12-182-1/+1
* | | | Merge branch 'master' into pushersDavid Baker2014-12-181-1/+3
|\ \ \ \ | | |/ / | |/| |
| * | | Workaround for non-uniqueness of room member events in the database confusing...Paul "LeoNerd" Evans2014-12-021-1/+3
| |/ /
* | | Thank you, pyflakesDavid Baker2014-12-181-1/+0
* | | ...and bump SCHEMA_VERSIONDavid Baker2014-12-181-1/+1
* | | Rename the pusher SQL delta to v9 which the next free oneDavid Baker2014-12-181-0/+0
* | | after a few rethinks, a working implementation of pushers.David Baker2014-12-184-30/+104
* | | Update to app_id / app_instance_id (partially) and mangle to be PEP8 compliant.David Baker2014-12-033-26/+38
* | | Merge branch 'develop' into pushersDavid Baker2014-12-026-24/+90
|\| |
| * | Don't return outliers when we get recent events for rooms.Erik Johnston2014-11-271-1/+1
| * | Don't delete the entire current_state_events tableErik Johnston2014-11-261-1/+4
| * | Add update delta for schema changeErik Johnston2014-11-262-1/+35
| * | Update schema to support multiple signaturesErik Johnston2014-11-261-1/+1
| * | Correctly handle the case where we get an event for an unknown room, which tu...Erik Johnston2014-11-262-16/+40
| |/
| * SYN-163: Add an order by rowid to selects.Erik Johnston2014-11-241-5/+10
* | More work on pushers. Attempt to do HTTP pokes. Not sure if the actual HTTP p...David Baker2014-11-213-4/+26
* | Merge branch 'develop' into pushersDavid Baker2014-11-207-23/+28
|\|
| * Fix pep8 codestyle warningsMark Haines2014-11-205-18/+24
| * Use module loggers rather than the root logger. Exceptions caused by bad clie...Mark Haines2014-11-202-2/+2
| * Add a few missing yields, Move deferred lists inside PreserveLoggingContext b...Mark Haines2014-11-202-3/+2
| * Bump version, changelog and upgrade.rstErik Johnston2014-11-191-1/+1
* | Start creating a module to do generic notifications (just prints them to stdo...David Baker2014-11-194-2/+158
|/
* SYN-104: When going backwards the end token should be before the last eventMark Haines2014-11-181-0/+3
* SYN-149: Send join event immediately after the room create eventMark Haines2014-11-181-0/+5
* Split out sending the room alias events from creating the alias so that we ca...Mark Haines2014-11-181-7/+12
* Merge PDUs and Events into one objectMark Haines2014-11-141-0/+8
* Fix PDU and event signaturesMark Haines2014-11-142-3/+3
* Merge branch 'develop' into request_loggingMark Haines2014-11-1417-1554/+1315
|\
| * Store all signatures on events rather than just dropping themErik Johnston2014-11-124-21/+31
| * Update some of the docs in event_federationErik Johnston2014-11-121-11/+20
| * Document StateStore and use transactionsErik Johnston2014-11-121-28/+56
| * Add indices to state group tablesErik Johnston2014-11-121-0/+13
| * Fix bugs with invites/joins across federatiom.Erik Johnston2014-11-122-6/+17
| * Fix bug where we /always/ created a new state groupErik Johnston2014-11-111-7/+2
| * Add an EventValidator. Fix bugs in auth ++ storageErik Johnston2014-11-103-20/+26
| * Fix regression where we did not return redacted events.Erik Johnston2014-11-101-1/+2
| * PEP8Erik Johnston2014-11-102-9/+7
| * Fix backfill to work. Add auth to backfill requestErik Johnston2014-11-102-2/+14
| * Notify users about invites.Erik Johnston2014-11-101-2/+1
| * Tidy up some of the unused sql tablesErik Johnston2014-11-103-107/+9
| * Finish redaction algorithm.Erik Johnston2014-11-101-1/+1
| * Add '/event_auth/' federation apiErik Johnston2014-11-071-7/+19
| * Fix bug in _get_auth_chain_txnErik Johnston2014-11-071-14/+11
| * Fix joining over federationErik Johnston2014-11-071-0/+1
| * Implement method to get auth_chain from a given event_idErik Johnston2014-11-071-0/+35
| * Start implementing auth chainsErik Johnston2014-11-075-1/+56
| * Amalgamate all power levels.Erik Johnston2014-11-062-169/+0
| * Implement new replace_state and changed prev_stateErik Johnston2014-11-064-59/+203
| * Get correct prev_eventsErik Johnston2014-11-052-15/+26
| * Remove unused importsErik Johnston2014-11-041-2/+0
| * For now, don't store txn -> pdu mappings.Erik Johnston2014-11-031-4/+3
| * FormattingErik Johnston2014-11-031-1/+4
| * Sign evnetsErik Johnston2014-10-311-0/+6
| * Remove unused signature storage methodsErik Johnston2014-10-311-138/+1
| * Remove unused sql file.Erik Johnston2014-10-311-31/+0
| * Make prev_event signing work again.Erik Johnston2014-10-312-7/+6
| * Remove more references to dead PDU tablesErik Johnston2014-10-312-75/+0
| * Remove PDU tables.Erik Johnston2014-10-314-1159/+1
| * Actually don't store any PDUsErik Johnston2014-10-311-0/+7
| * Don't store any PDUsErik Johnston2014-10-311-9/+9
| * Move the impl of backfill to use events.Erik Johnston2014-10-311-1/+85
| * Merge branch 'develop' of github.com:matrix-org/synapse into federation_autho...Erik Johnston2014-10-302-4/+7
| |\
| * | Fix SQL so that accepts we may want to persist events twice.Erik Johnston2014-10-302-25/+47
| * | Start filling out and using new events tablesErik Johnston2014-10-294-46/+89
| * | Don't reference PDU when persisting eventErik Johnston2014-10-282-4/+5
| * | Begin implementing all the PDU storage stuff in Events landErik Johnston2014-10-287-37/+475
| * | Add transaction level logging and timing information. Add a _simple_delete me...Erik Johnston2014-10-289-21/+91
| * | Clean up LoggingTransactionErik Johnston2014-10-281-10/+4
| * | Add timer to LoggingTransactionErik Johnston2014-10-281-3/+10
| * | Merge branch 'event_signing' of github.com:matrix-org/synapse into federation...Erik Johnston2014-10-275-14/+288
| |\ \
| | * | fix pyflakes warningsMark Haines2014-10-271-2/+0
| | * | Merge branch 'develop' into event_signingMark Haines2014-10-273-5/+36
| | |\ \
| | * \ \ Merge branch 'develop' into event_signingMark Haines2014-10-173-7/+11
| | |\ \ \
| | * | | | Hash the same content covered by the signature when referencing previous PDUs...Mark Haines2014-10-174-9/+66
| | * | | | Include hashes of previous pdus when referencing themMark Haines2014-10-164-12/+77
| | * | | | Sign outgoing PDUs.Mark Haines2014-10-162-6/+7
| | * | | | persist hashes and origin signatures for PDUsMark Haines2014-10-153-5/+31
| | * | | | Storage for pdu signaturesMark Haines2014-10-142-0/+126
| * | | | | Merge branch 'develop' of github.com:matrix-org/synapse into federation_autho...Erik Johnston2014-10-274-11/+47
| |\ \ \ \ \
| * | | | | | Use state groups to get current state. Make join dance actually work.Erik Johnston2014-10-172-0/+9
| * | | | | | Begin making auth use event.old_state_eventsErik Johnston2014-10-152-2/+2
| * | | | | | Add missing package storate.stateErik Johnston2014-10-151-0/+97
| * | | | | | Begin implementing state groups.Erik Johnston2014-10-142-1/+38
| | |/ / / / | |/| | | |
* | | | | | Merge branch 'develop' into request_loggingMark Haines2014-10-302-4/+7
|\ \ \ \ \ \ | | |_|_|_|/ | |/| | | |
| * | | | | Fix pep8 warningsMark Haines2014-10-302-4/+7
| | |_|_|/ | |/| | |
* / | | | Add a request-id to each log lineMark Haines2014-10-301-4/+12
|/ / / /
* | / / Fix pyflakes warningsMark Haines2014-10-271-1/+0
| |/ / |/| |
* | | Wrap preparing the database in a transaction. Otherwise it will take many sec...Mark Haines2014-10-241-3/+4
* | | Bump database version number.Erik Johnston2014-10-172-1/+32
| |/ |/|
* | keep 'origin_server_ts' as 'ts' in the database to avoid needlessly updating ...Mark Haines2014-10-176-11/+15
* | SPEC-7: Rename 'ts' to 'origin_server_ts'Mark Haines2014-10-175-12/+12
|/
* Respond with more helpful error messages for unsigned requestsMark Haines2014-10-132-4/+9
* Merge branch 'develop' into server2server_signingMark Haines2014-09-3012-33/+227
|\
| * pyflakes cleanupErik Johnston2014-09-302-2/+1
| * SYN-2: Allow server admins to delete room aliasesErik Johnston2014-09-301-0/+30
| * Update docstringErik Johnston2014-09-291-1/+2
| * SYN-48: Delete dead codeErik Johnston2014-09-291-26/+0
| * SYN-48: Implement WHOIS rest servletErik Johnston2014-09-294-15/+57
| * Add auth check to test if a user is an admin or not.Erik Johnston2014-09-291-0/+8
| * SYN-48: Track User-Agents as well as IPs for client devices.Erik Johnston2014-09-293-4/+10
| * Track the IP users connect with. Add an admin column to users table.Erik Johnston2014-09-263-1/+35
| * Merge branch 'deletions' of github.com:matrix-org/synapse into developErik Johnston2014-09-258-19/+118
| |\
| | * Add LIMIT to scalar subqueryErik Johnston2014-09-253-5/+10
| | * Rename deletions to redactionsErik Johnston2014-09-249-49/+52
| | * Make deleting deletes not undeleteErik Johnston2014-09-241-14/+4
| | * Fix bug where we didn't correctly pull out the event_id of the deletionErik Johnston2014-09-242-3/+8
| | * Add v4 deltas to current sql.Erik Johnston2014-09-243-1/+10
| | * Rename 'pruned' to 'pruned_because'Erik Johnston2014-09-232-2/+2
| | * SYN-12: Implement auth for deletion by adding a 'delete_level' on the ops lev...Erik Johnston2014-09-232-3/+11
| | * Make sure we don't persist the 'pruned' keyErik Johnston2014-09-231-1/+1
| | * Add m.room.deletion. If an event is deleted it will be returned to clients 'p...Erik Johnston2014-09-235-17/+91
| | * Add a deletions tableErik Johnston2014-09-221-0/+5
| * | Fix bug where we tried to insert state events with null state keyErik Johnston2014-09-251-1/+2
| |/
* / SYN-75 Verify signatures on server to server transactionsMark Haines2014-09-303-37/+52
|/
* SYN-47: Fix bug where we still returned events for rooms we had left.Erik Johnston2014-09-191-1/+1
* Merge branch 'develop' into test-sqlite-memoryPaul "LeoNerd" Evans2014-09-171-5/+10
|\
| * Correctly handle receiving 'missing' Pdus from federation, rather than just d...Erik Johnston2014-09-151-5/+10
* | Merge remote-tracking branch 'origin/develop' into test-sqlite-memoryPaul "LeoNerd" Evans2014-09-153-3/+13
|\|
| * Correctly handle the 'age' key in events and pdusErik Johnston2014-09-151-0/+4
| * Fix bug where we relied on the current_state_events being updated when we are...Erik Johnston2014-09-121-2/+2
| * Fix bug where we no longer stored user_id on PdusErik Johnston2014-09-121-1/+7
* | Merge remote-tracking branch 'origin/develop' into test-sqlite-memoryPaul "LeoNerd" Evans2014-09-123-84/+64
|\|
| * Make the state resolution use actual power levels rather than taking them fro...Erik Johnston2014-09-122-71/+18
| * Fix bug where we incorrectly removed a remote host from the list of hosts in ...Erik Johnston2014-09-121-12/+45
| * Fix bug where we didn't return a tuple when expected.Erik Johnston2014-09-121-1/+1
* | More accurate docs / clearer paramter names in RoomMemberStorePaul "LeoNerd" Evans2014-09-121-6/+7
* | Revert recent changes to RoomMemberStorePaul "LeoNerd" Evans2014-09-122-28/+10
* | Now don't need the other logger.debug() call in _executePaul "LeoNerd" Evans2014-09-121-5/+0
* | Logging of all SQL queries via the 'synapse.storage.SQL' loggerPaul "LeoNerd" Evans2014-09-121-2/+43
* | Add a .runInteraction() method on SQLBaseStore itself to wrap the .db_poolPaul "LeoNerd" Evans2014-09-128-33/+42
* | Add a better _store_room_member_txn() method that takes separated fields inst...Paul "LeoNerd" Evans2014-09-111-8/+21
* | Rename _store_room_member_txn to _store_room_member_from_event_txn so we can ...Paul "LeoNerd" Evans2014-09-112-2/+2
* | prepare_database() on db_conn, not plain name, so we can pass in the connecti...Paul "LeoNerd" Evans2014-09-101-31/+26
* | Move database preparing code out of homserver.py into storage where it belongsPaul "LeoNerd" Evans2014-09-101-0/+61
|/
* Fix bug where we used an unbound local variable if we ended up rolling back t...Erik Johnston2014-09-091-4/+1
* Apparently we can't do txn.rollback(), so raise and catch an exception instead.Erik Johnston2014-09-081-11/+19
* Fix bug in state handling where we incorrectly identified a missing pdu. Upda...Erik Johnston2014-09-081-3/+6
* Rollback if we try and insert duplicate eventsErik Johnston2014-09-081-0/+1
* When getting a state event also include the previous contentErik Johnston2014-09-064-12/+37
* Generate m.room.aliases event when the HS creates a room aliasErik Johnston2014-09-052-0/+34
* Add support to _simple_insert() to do INSERT OR REPLACEPaul "LeoNerd" Evans2014-09-031-4/+6
* fix the copyright holder from matrix.org to OpenMarket Ltd, as matrix.org has...Matthew Hodgson2014-09-0323-23/+23
* Store SQL DDL deltas as well; attempt to upgrade the database on startup if i...Paul "LeoNerd" Evans2014-09-031-0/+168
* Rename the 'do_users_share_a_room' to something slightly less verb-soundingPaul "LeoNerd" Evans2014-09-031-1/+1
* Add copyright notices and fix pyflakes errorsMark Haines2014-09-031-0/+15
* Fix bug where we didn't correctly store the ops power levels event.Erik Johnston2014-09-022-1/+4
* Merge branch 'develop' of github.com:matrix-org/synapse into room_configErik Johnston2014-09-013-1/+135
|\
| * Fix homeserver config parsingMark Haines2014-09-011-1/+1
| * Merge branch 'develop' into server2server_tlsMark Haines2014-08-311-3/+6
| |\
| * | Add store for server certificates and keysMark Haines2014-08-283-1/+135
* | | Add all the necessary checks to make banning work.Erik Johnston2014-09-012-3/+2
* | | Add beginnings of ban support.Erik Johnston2014-09-013-7/+63
* | | Implement power level lists, default power levels and send_evnet_level/add_st...Erik Johnston2014-09-013-22/+99
* | | Start adding storage for new events.Erik Johnston2014-08-293-0/+121
| |/ |/|
* | Get the equalities right.Erik Johnston2014-08-291-2/+5
* | Initial room event stream token must be s0, not s1, or everyone will miss the...Paul "LeoNerd" Evans2014-08-281-1/+1
|/
* Merge branch 'develop' into storage_transactionsMark Haines2014-08-271-2/+2
|\
| * Merge branch 'develop' of github.com:matrix-org/synapse into stream_refactorErik Johnston2014-08-271-1/+0
| |\
| * \ Merge branch 'develop' of github.com:matrix-org/synapse into stream_refactorErik Johnston2014-08-261-2/+2
| |\ \
| * | | WIP: Completely change how event streaming and pagination work. This reflects...Erik Johnston2014-08-261-2/+2
* | | | Return the store_id from persist_eventMark Haines2014-08-271-1/+3
* | | | add _get_room_member, fix datastore methodsMark Haines2014-08-272-8/+26
* | | | Fill out prev_events before calling persist_eventMark Haines2014-08-271-6/+15
* | | | Remove unused populate_previous_pdusMark Haines2014-08-271-6/+1
* | | | Merge branch 'develop' into storage_transactionsMark Haines2014-08-272-3/+2
|\ \ \ \ | | |_|/ | |/| |
| * | | Added support for GET /events/$eventid with auth checks.Kegan Dougal2014-08-271-1/+0
| | |/ | |/|
| * | Feedback: Removed FeedbackRestServlet. Modified keys on FeedbackEvent. Expand...Kegan Dougal2014-08-261-2/+2
| |/
* | Fold federation/handler into handlers/federationMark Haines2014-08-261-1/+3
* | Move pdu and event persistence into a single persist_event functionMark Haines2014-08-262-21/+33
* | Merge branch 'develop' into storage_transactionsMark Haines2014-08-267-27/+69
|\|