sha,message,author_date,committer_date,raw_author,raw_committer,repo,author,committer 12f7e1dc5624d14f644abead18bd90b420b6d97e,"Hashed URLs now have far-future cache expiry Since the URL now includes a hash of the database, we can return a Cache- Control: max-age=31536000 header for every response. The exception is our 302 redirects. These we now serve with a Link: header that tells any HTTP/2 server-push aware fronting proxies (such as Cloudfront) to push the target of the redirect. Closes #4",2017-10-24T02:36:44Z,2017-10-24T02:36:44Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 195a5b36349d0d24a6bbb758cebb719b6de303b6,"Heroku --include-vcs-ignore (#407) Means `datasette publish heroku` can work under Travis, unlike this failure: https://travis-ci.org/simonw/fivethirtyeight-datasette/builds/488047550 ``` 2.25s$ datasette publish heroku fivethirtyeight.db -m metadata.json -n fivethirtyeight-datasette tar: unrecognized option '--exclude-vcs-ignores' Try 'tar --help' or 'tar --usage' for more information. ▸ Command failed: tar cz -C /tmp/tmpuaxm7i8f --exclude-vcs-ignores --exclude ▸ .git --exclude .gitmodules . > ▸ /tmp/f49440e0-1bf3-4d3f-9eb0-fbc2967d1fd4.tar.gz ▸ tar: unrecognized option '--exclude-vcs-ignores' ▸ Try 'tar --help' or 'tar --usage' for more information. ▸ The command ""datasette publish heroku fivethirtyeight.db -m metadata.json -n fivethirtyeight-datasette"" exited with 0. ``` The fix for that issue is to call the heroku command like this: heroku builds:create -a app_name --include-vcs-ignore",2019-02-06T04:15:46Z,2019-02-06T04:15:46Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 65e350ca2a4845c25752a62c16ba58cfe2c14b9b,"Implemented 'datasette publish one.db two.db' command Closes #26",2017-11-11T07:25:22Z,2017-11-11T07:25:22Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 21c9c04310dffcdb8cf6fee0f74fc9e7ac1ecf19,"Implemented cursor-based pagination for table view Closes #5",2017-11-10T20:41:14Z,2017-11-10T20:41:14Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 59580d02da80eb963d5bce897c539c6489042025,"Implemented custom SQL via textarea Closes #65",2017-11-12T02:35:35Z,2017-11-12T02:35:35Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 2a9799bae651558a23ae5074edad7cc13ff0fbdc,"Implemented database summary on index page Closes #41",2017-10-27T04:05:13Z,2017-10-27T04:05:17Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 b2372605d63248f422b6e67cb5c392236a3aa612,"Implemented multi-db support plus initial URL structure Refs #24 Fixes #15",2017-10-24T02:00:37Z,2017-10-24T02:00:37Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 fd3a33989aaf2533c4928de3b251c24614003f1e,"Implemented new database view and template Closes #53 - see comments there for screenshots.",2017-11-12T01:50:21Z,2017-11-12T01:50:21Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 847f3e0c92b5ac17200b2090bedcc5443bb08e4b,"Implemented offset/limit pagination for views Closes #70",2017-11-13T21:10:55Z,2017-11-13T21:10:55Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 7d81083d40fb2749be897d89c9a094d6521ef20c,"Implemented responsive tables, removed bootstrap No need for all of bootstrap since we only need to style a few elements. Implemented responsive table pattern from here: https://css-tricks.com/responsive-data-tables/ Refs #16",2017-11-11T05:55:50Z,2017-11-11T05:55:50Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 b20d7119e4f6506cdb9d5d11322e28130823adfd,Implemented template inheritance and brought back errors,2017-10-24T02:56:27Z,2017-10-24T02:56:27Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 666aa032530189d585dd61d0e9851e9fe63ee598,"Improved error handling Invalid SQL now shows a special error.html template, and is covered by tests.",2017-11-12T21:16:15Z,2017-11-12T21:16:15Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 7dac1c05cd40f89a5af34763e4d5614c750575c2,"Improved pagination Closes #78",2017-11-13T20:34:56Z,2017-11-13T20:34:56Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 a4af532a31ece7095d710a1f5abb39ea93fe003f,"Include foreign key info in inspect() output Refs #85",2017-11-16T01:34:32Z,2017-11-16T01:34:32Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 4fec50597a8684756bc96d4a69b6fab809ec6cf6,Include license/source in JSON output if provided,2017-11-13T18:39:25Z,2017-11-13T18:39:25Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 c371f06fdea413cfb00aa8f81b7a5535a7ecdbc4,Include took_ms in JSON output,2017-10-24T23:55:53Z,2017-10-24T23:55:53Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 2f34da0ab2594d917e14fd0dd90ad07872941b8d,Initial,2018-07-14T03:56:21Z,2018-07-14T03:56:21Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,140912432,9599,9599 ac9d66817d6a08b806f8e4bc16da02fbdb430496,Initial commit,2017-10-23T00:39:03Z,2017-10-23T00:39:03Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 bd71be32abead38ec0b69695347219024efea0fe,Initial project layout + database table creation tools,2018-07-28T13:43:18Z,2018-07-28T13:46:17Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,140912432,9599,9599 407795b61217205625f2d4e084afbf69f1db781b,"Initial unit tests against our Sanic app Refs #50 I had to disable the build metadata function to get these tests to work sensibly. I need to completely rethink how that mechanism works.",2017-11-11T17:47:59Z,2017-11-11T17:47:59Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 de04d7a854d71003ffcf98028eab976a936c2dba,Initial working proof of concept,2017-10-23T00:41:19Z,2017-10-23T00:41:19Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 f3445e2d13e2c38bfbf75f35c2aa3e50df0040f1,Install python3-dev rothar than python-dev,2017-11-17T14:18:49Z,2017-11-17T14:18:49Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 ad8b5d3bd23a7b306b8843d7de53a7c918ddb74f,"JSON version of our homepage Now available at http://localhost:8006/.json Tested by tests added in 407795b61217205625f2d4e084afbf69f1db781b",2017-11-11T17:49:47Z,2017-11-11T17:49:47Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 8252e71da461c425e625e1c3e4ee0bd92ea4cbf0,"Limit on max rows returned, controlled by --max_returned_rows option If someone executes 'select * from table' against a table with a million rows in it, we could run into problems: just serializing that much data as JSON is likely to lock up the server. Solution: we now have a hard limit on the maximum number of rows that can be returned by a query. If that limit is exceeded, the server will return a `""truncated"": true` field in the JSON. This limit can be optionally controlled by the new `--max_returned_rows` option. Setting that option to 0 disables the limit entirely. Closes #69",2017-11-13T19:33:01Z,2017-11-13T19:33:01Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 ea0a761303d84bd73f54a1acedc45b01c38b2da0,Link to documentation from README,2018-04-21T00:20:56Z,2018-04-21T00:20:56Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 b46e370ee6126aa2fa85cf789a31da38aed98496,"Link to pages-per-row Closes #1",2017-10-24T14:10:58Z,2017-10-24T14:10:58Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 7f44d31782260f859af1de68ac9db29f72cc6d84,Link to register-of-members-interests tutorial,2018-04-25T17:40:48Z,2018-04-25T17:40:48Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 f9c32e717f67b55e5d51bb896adc2dcec4489c2d,Linked to csvs-to-sqlite,2017-12-06T15:09:56Z,2017-12-06T15:09:56Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 741e8f7fe563e18fe9a12ac1ce38157e8c903505,"Make .indexes compatible with older SQLite versions (#1) Older SQLite versions return a different set of columns from the PRAGMA we are using.",2018-08-02T15:17:29Z,2018-08-02T15:17:29Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,140912432,9599,19864447 59a616ca5c99301a254d86ab097b6ce8f7b30fb6,"Move view SQL to bottom of the page Now consistent with tables",2017-11-12T21:25:34Z,2017-11-12T21:25:34Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 31b21f5c5e15fc3acab7fabb170c1da71dc3c98c,"Moved all SQLite queries to threads SQLite operations are blocking, but we're running everything in Sanic, an asyncio web framework, so blocking operations are bad - a long-running DB operation could hold up the entire server. Instead, I've moved all SQLite operations into threads. These are managed by a concurrent.futures ThreadPoolExecutor. This means I can run up to X queries in parallel, and I can continue to queue up additional incoming HTTP traffic while the threadpool is busy. Each thread is responsible for managing its own SQLite connections - one per database. These are cached in a threadlocal. Since we are working with immutable, read-only SQLite databases it should be safe to share SQLite objects across threads. On this assumption I'm using the check_same_thread=False option. Opening a database connection looks like this: conn = sqlite3.connect( 'file:filename.db?immutable=1', uri=True, check_same_thread=False, ) The following articles were helpful in figuring this out: * https://pymotw.com/3/asyncio/executors.html * https://marlinux.wordpress.com/2017/05/19/python-3-6-asyncio-sqlalchemy/ Closes #45. Refs #38.",2017-11-05T02:21:44Z,2017-11-05T02:21:44Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 fcc38b9ff2e4dbb680a4429002767f6df855674b,Moved fixtures into conftest.py,2018-08-13T00:24:11Z,2018-08-13T00:25:39Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,140912432,9599,9599 c446e22f34eb56a454c57edf93824d2615b83c0e,"Moved fixtures to fixtures.py, added .schema test",2018-07-31T15:55:24Z,2018-07-31T15:55:24Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,140912432,9599,9599 b2955d9065ea019500c7d072bcd9d49d1967f051,"New --plugins-dir=plugins/ option (#212) * New --plugins-dir=plugins/ option New option causing Datasette to load and evaluate all of the Python files in the specified directory and register any plugins that are defined in those files. This new option is available for the following commands: datasette serve mydb.db --plugins-dir=plugins/ datasette publish now/heroku mydb.db --plugins-dir=plugins/ datasette package mydb.db --plugins-dir=plugins/ * Unit tests for --plugins-dir=plugins/ Closes #211",2018-04-16T05:22:01Z,2018-04-16T05:22:01Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 0abd3abacb309a2bd5913a7a2df4e9256585b1bb,"New ?_shape=objects/object/lists param for JSON API (#192) New _shape= parameter replacing old .jsono extension Now instead of this: /database/table.jsono We use the _shape parameter like this: /database/table.json?_shape=objects Also introduced a new _shape called 'object' which looks like this: /database/table.json?_shape=object Returning an object for the rows key: ... ""rows"": { ""pk1"": { ... }, ""pk2"": { ... } } Refs #122",2018-04-03T14:52:54Z,2018-04-03T14:52:54Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 9cb69cbd45ed8fd93190c47060c19abec80bc4ef,"New ?_sql_time_limit_ms=10 argument to database and table page Allows callers to opt for a lower time limit. Closes #95",2017-11-15T02:55:10Z,2017-11-15T02:55:10Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 9eacd30b1d6e3f1bd138fb330cfea4830197cb1d,New column_order= parameter for setting column order,2018-08-08T23:06:49Z,2018-08-08T23:06:49Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,140912432,9599,9599 4143e3b45c16cbae5e3e3419ef479a71810e7df3,"New command: datasette package - packages a docker container Example usage: datasette package fivethirtyeight.db \ --tag fivethirtyeight \ --metadata=538-metadata.json This will create a temporary directory, generate a Dockerfile, copy in the SQLite database and metadata file, then build that as a new docker image and tag that in your local Docker repository as fivethirtyeight:latest. You can then run the image like so: docker run -p 8006:8001 fivethirtyeight This will expose port 8001 in the container (the default) as port 8006 on your host. Closes #67",2017-11-13T16:13:38Z,2017-11-13T16:17:35Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 56623e48da5412b25fb39cc26b9c743b684dd968,News: Datasette Publish,2018-01-17T15:50:10Z,2018-01-17T15:50:10Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 a0bb9da17fb95ac5e3bcd3c8d800d33c25a71bbc,"Now requires DB files to be passed as arguments Refs #40",2017-11-06T02:24:43Z,2017-11-06T02:24:43Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 7e0cedae3d920797f6f9411aea90a2b1d86ac9c7,"Now using bootstrap 4 beta Refs #16",2017-11-06T02:49:07Z,2017-11-06T02:49:07Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 5deb65f0623bff03421f50d3c61f699b981ae18b,"Now you just 'from sqlite_utils import Database' Plus fixed ad_id in the Russian ads example in the docs",2018-07-31T03:30:23Z,2018-07-31T03:30:23Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,140912432,9599,9599 9f47b6e4d80f0f393cf0167a6f48280de6847d1d,"Pin to specific Jinja version Closes #100",2017-11-16T00:14:07Z,2017-11-16T00:14:07Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 0d63128c40aec15a958dddf181c13e0db1c7908b,"Preparing v0.2, first release to PyPI",2018-07-29T00:42:41Z,2018-07-29T00:42:41Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,140912432,9599,9599 f1b0521810bbc467721e4dcc5a2ff1bf2a1ddbb8,Preserve .json through redirects,2017-10-25T15:01:22Z,2017-10-25T15:01:22Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 67ad77a307c7c264c68d768fa8290997e3b75e77,Re-ordered docs index page,2017-12-06T18:27:50Z,2017-12-06T18:27:50Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 02b1814fcfdc61b1b69b5955f2b60252ff10cde9,"Redirects now preserve query string Fixes #28",2017-10-24T23:54:26Z,2017-10-24T23:54:26Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 1fc75809a6aa17860944b4cc3a4d7175cd53b1f4,"Refactored everything into a factory function I now call a factory function to construct the Sanic app: app = app_factory(files) This allows me to pass additional arguments to it, e.g. the files to serve. Also refactored my class-based views to accept jinja as an argument, e.g: app.add_route( TableView.as_view(jinja), '//' )",2017-11-05T02:13:44Z,2017-11-05T02:13:44Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 e16ca1169cc49fbb5b0325564d248becad3a4b7f,"Refactored table column/row display logic Simplified the template and made the way for upcoming foreign key work. Refs #85 Also fixed   bug on database page - closes #113",2017-11-17T15:39:36Z,2017-11-17T15:39:36Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 40d3b3eae68286f67e40226f18f2621b26e5e533,"Refactored tests into new tests/ folder Guided by https://docs.pytest.org/en/latest/goodpractices.html",2017-11-10T18:48:16Z,2017-11-10T18:48:16Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 9d219140694551453bfa528e0624919eb065f9d6,"Refactored to use class based views Closes #22",2017-10-24T02:25:48Z,2017-10-24T02:25:48Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 a8a293cd71f7529aff374be5ca01f2ebd5e71ee4,Refactored util functions into new utils module,2017-11-10T19:25:54Z,2017-11-10T19:25:54Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 f5418e13f2e435a42cd3611b28ec3c9ac02481da,Release 0.3.1 to publish updated README to PyPI,2018-07-31T15:39:43Z,2018-07-31T15:39:43Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,140912432,9599,9599 d75f423b6fcfc074b7c6f8f7679da8876f181edd,Release 0.9,2017-11-13T22:00:39Z,2017-11-13T22:00:53Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 0d3479ba320e5a5d15f029838744c5219a9e2987,Release notes for 0.13,2017-11-25T03:32:24Z,2017-11-25T03:32:24Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 6b3b05b6db0d2a7b7cec8b8dbb4ddc5e12a376b2,Released 0.7,2017-11-13T18:42:30Z,2017-11-13T18:42:30Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 d76412668f8c12572eb7de57ccb72f1e50306177,Removed rogue middot,2017-11-13T20:34:39Z,2017-11-13T20:34:39Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 25c241fa5a0f8868e3c1bc5be4f5888caa47d864,Renamed project to immutabase,2017-11-06T02:32:13Z,2017-11-06T02:32:13Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 e7e50875d341f1d26b4dbba862f5202631f34896,Renamed to 'datasette',2017-11-10T18:38:35Z,2017-11-10T18:38:35Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 1c57bd202fb1f82e14c47dfca63454352999732c,"Replaced app_factory with new Datasette class This should make it easier to add unit tests.",2017-11-10T19:05:57Z,2017-11-10T19:05:57Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 e9e1def4c0cc49c96ed0b0d2bbc3ae81353ed2bb,"Revised JSON design a bit Closes #63",2017-11-11T22:20:00Z,2017-11-11T22:20:00Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 40a563ebac72f46a1b2dc498a25520c429bca6d6,"Reworked metadata building options Building metadata is now optional. If you want to do it, do this: datasette build *.db --metadata=metadata.json Then when you run the server you can tell it to read from metadata: datasette serve *.db --metadata=metadata.json The Dockerfile generated by datasette publish now uses this mechanism. Closes #60",2017-11-11T20:10:51Z,2017-11-11T20:11:51Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 6a007f632258e6cfd3c5e9e229683deb0efd87be,Row pages show incoming foreign key relationships,2017-11-17T18:15:44Z,2017-11-18T03:15:49Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 3a944d0c077c203277f13dd69387eb84b5c88d3e,Run Travis tests against Python 3.8-dev (#5),2019-01-26T02:37:54Z,2019-01-26T02:37:54Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,140912432,9599,19864447 fa8eb0bf1b113ab17ede9cd107b7c3bd5cde39c3,Run unit tests against both Python 3.5 and 3.6,2017-11-22T17:43:52Z,2017-11-22T17:43:52Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 28a52fcffb869f5e83ca2fad53738dc25eec425d,Set theme jekyll-theme-architect,2018-05-24T16:56:21Z,2018-05-24T16:56:21Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 3d9baf3c2f2f745e6949973f18480092f189116c,Set theme jekyll-theme-leap-day,2018-05-24T16:55:19Z,2018-05-24T16:55:19Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 6823b094066c5cb1dcd3581da2ed877ed72298b7,"Set time limit of 1000ms on SQL queries Using the (undocumented in the Python docs) fact that if you return 1 from a set_progress_handler callback, SQLite will cancel the current query. Closes #35",2017-10-25T01:34:54Z,2017-10-25T01:34:54Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 d01370f1660d0b0360248105cd43060dca31f70f,Show SQL and params if table has them applied,2017-11-12T23:21:39Z,2017-11-12T23:21:39Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 03c58fb350f6b9bb941a46907da5ac6f67bf47cf,Show databases in alphabetical order on index page,2017-11-10T19:04:56Z,2017-11-10T19:04:56Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 bd5f3b2ba1a627383d512d613b77d15501dfccc4,Show time taken at bottom of table page,2017-10-25T01:31:54Z,2017-10-25T01:31:54Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 eef213ab4d57622dfc60c8655c0c7a18afcc844f,Show total number of rows in table,2017-10-25T00:11:36Z,2017-10-25T00:11:36Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 3eb79e1a5fa4c164a224ae0adbe0ea16fde35758,Show total row count at top of table page,2017-10-25T01:31:43Z,2017-10-25T01:31:43Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 47e689a89b3f5f0969595b17d2ec59ea3caffb3b,"Speed up Travis by reusing pip wheel cache across builds (#324) * Cache pip wheels between runs in Travis, refs #323 * Run pytest manually - ""python setup.py test"" appeared to still download a bunch of stuff: https://travis-ci.org/simonw/datasette/jobs/395306188 * Use extras_require so pip can install test dependencies: https://github.com/pypa/pip/issues/1197#issuecomment-228939212",2018-06-24T01:03:46Z,2018-06-24T01:03:46Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 33c7c53ff87c25445c68088ede49d062d9c31fe8,"Start of the plugin system, based on pluggy (#210) Uses https://pluggy.readthedocs.io/ originally created for the py.test project We're starting with two plugin hooks: prepare_connection(conn) This is called when a new SQLite connection is created. It can be used to register custom SQL functions. prepare_jinja2_environment(env) This is called with the Jinja2 environment. It can be used to register custom template tags and filters. An example plugin which uses these two hooks can be found at https://github.com/simonw/datasette-plugin-demos or installed using `pip install datasette-plugin-demos` Refs #14",2018-04-16T00:56:15Z,2018-04-16T00:56:15Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 594b25ef9f633dabdaca98b46dea9fbb82628166,"Started a changelog, releasing 0.6",2018-08-13T00:46:22Z,2018-08-13T00:46:22Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,140912432,9599,9599 1ae8ea0f03cfb9f25b1e25f3194c456c3649789c,"Started implementing ?name__contains=X filters So far we support __contains=, __startswith=, __endswith= and __exact= Refs #23",2017-10-25T00:06:23Z,2017-10-25T00:06:23Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 29c897bb5649c35463618a32d095f72755aae8c6,Started the docs with a meaty example,2018-07-28T23:52:07Z,2018-07-28T23:52:07Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,140912432,9599,9599 1592fd0419f374de201926d3ba67fbf1522eed13,"Started work on cli, which also meant adding setup.py I'm using click, and click recommends using a setup.py - so I've added one of those. I also refactored code into a new datasite package. It's not quite deploying to now properly at the moment though - I seem to have messed up the path handling a bit. Also snuck in a new template for the ""Row"" view. Refs #40",2017-10-27T07:08:24Z,2017-10-27T07:08:24Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 44a199a0625b695492b2a8605030dc61191f39cb,"Stop using sqlite WITH RECURSIVE in our tests The version of Python 3 running in Travis CI doesn't support this.",2017-11-13T22:15:21Z,2017-11-13T22:15:21Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 95bce37ad3447d3c265316fa029fc09b7bbdae11,Store list/dict/tuple values as JSON strings,2018-07-28T22:20:29Z,2018-07-28T22:20:29Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,140912432,9599,9599 fc3660cfad7668dbce6ead12766e048fc1f78b11,"Streaming mode for downloading all rows as a CSV (#315) * table.csv?_stream=1 to download all rows - refs #266 This option causes Datasette to serve ALL rows in the table, by internally following the _next= pagination links and serving everything out as a stream. Also added new config option, allow_csv_stream, which can be used to disable this feature. * New config option max_csv_mb limiting size of CSV export",2018-06-18T03:21:02Z,2018-06-18T03:21:02Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 2bbe9ca34a701191e3bf4e97943b7503a50ab548,Support OPTIONS requests for CORS,2017-11-13T02:11:52Z,2017-11-13T02:11:52Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 e615d22c5564ea1f32abb086088b2700110be10a,"Support for numpy types, closes #11 (#12)",2019-02-24T04:02:19Z,2019-02-24T04:02:19Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,140912432,9599,19864447 72644b6e3fc78ecf55b386854943ec3ad39f97bd,"Support method chaining, added .last_id for accessing lastrowid Also shipping as 0.5",2018-08-06T01:42:43Z,2018-08-06T01:42:43Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,140912432,9599,9599 186c513a61a091b9f83d788e25b08f41a84ed9a3,"Support parameterized SQL and block potentially harmful queries You can now call arbitrary SQL like this: /flights?sql=select%20*%20from%20airports%20where%20country%20like%20:c&c=iceland Unescaped, those querystring params look like this: sql = select * from airports where country like :c c = iceland So SQL can be constructed with named parameters embedded in it, which will then be read from the querystring and correctly escaped. This means we can aggressively filter the SQL parameter for potentially dangerous syntax. For the moment we enforce that it starts with a SELECT statement and we ban the sequence ""pragma"" from it entirely. If you need to use pragma in a query, you can use the new named parameter mechanism. Fixes #39",2017-11-05T02:49:18Z,2017-11-05T02:49:18Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 084350b0f1343d988928cae63cfedbeb6205e25e,"Switched to gather_request=False for Sanic tests Gets rid of those ugly _, response = lines.",2017-11-17T14:53:37Z,2017-11-17T14:53:37Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 22851ed9f0541904f5c3fca7ddbd7add10a75d39,"Table page now shows CREATE TABLE at bottom Closes #66",2017-11-12T21:16:59Z,2017-11-12T21:16:59Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 1b04662585ea1539014bfbd616a8112b650d5699,"Table views now show expanded foreign key references, if possible If a table has foreign key columns, and those foreign key tables have label_columns, the TableView will now query those other tables for the corresponding values and display those values as links in the corresponding table cells. label_columns are currently detected by the inspect() function, which looks for any table that has just two columns - an ID column and one other - and sets the label_column to be that second non-ID column.",2017-11-18T03:09:32Z,2017-11-18T03:15:49Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 0b8c1b0a6da9cb8ac0d28cc90dd783de87554036,"Test for sql_time_limit_ms + sqlite_functions mechanism Added a unit test for the sql_time_limit_ms option. To test this, I needed to add a custom SQLite sleep() function. I've added a simple mechanism to the Datasette class for registering custom functions. I also had to modify the sqlite_timelimit() function. It makes use of a magic value, N, which is the number of SQLite virtual machine instructions that should execute in between calls to my termination decision function. The value of N was not finely grained enough for my test to work - so I've added logic that says that if the time limit is less than 50ms, N is set to 1. This got the tests working. Refs #95",2017-11-15T02:41:03Z,2017-11-15T02:43:34Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 8acdc2fd14c0f7251e1e3fd592c53b3152f5256c,"Test for table with space in name Tests code in b51836f8463ef65bc947f0a7b6e60167cb7154cf",2017-11-12T20:08:32Z,2017-11-12T20:08:32Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 0e5f51adfeff24a120bbdf0e5ac5669b18124400,Three more news items,2018-03-30T07:03:45Z,2018-03-30T07:03:45Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 82261a638bd35c9d69a9582a898cf4dab374f76c,"Turn on auto-escaping in Jinja We had XSS holes! Since we don't do cookies or authentication they shouldn't cause any actual harm, but still really not good. https://github.com/pallets/jinja/issues/528",2017-11-16T01:59:42Z,2017-11-16T01:59:42Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 70e1f831a00ec97b724187025e35338becd2309a,Typo,2018-08-01T01:32:03Z,2018-08-01T01:32:03Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,140912432,9599,9599 6f6d0ff2b41f1cacaf42287b1b230b646bcba9ee,"URL hashing is now off by default - closes #418 Prior to this commit Datasette would calculate the content hash of every database and redirect to a URL containing that hash, like so: https://v0-27.datasette.io/fixtures => https://v0-27.datasette.io/fixtures-dd88475 This assumed that all databases were opened in immutable mode and were not expected to change. This will be changing as a result of #419 - so this commit takes the first step in implementing that change by changing this default behaviour. Datasette will now only redirect hash-free URLs under two circumstances: * The new `hash_urls` config option is set to true (it defaults to false). * The user passes `?_hash=1` in the URL",2019-03-17T22:55:04Z,2019-03-17T22:55:04Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 3cce63b59851495b6d9d38936356e21ea8fbad3a,"URL to allow direct database download It's just the database URL with .db on the end, e.g. /flights.db Closes #19",2017-10-25T15:19:32Z,2017-10-25T15:19:32Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599 3c50a3600d0975b84d98c93bb2336a790afc6aca,Unit test for black-approved coding style,2018-07-28T14:29:20Z,2018-07-28T14:29:20Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,140912432,9599,9599 dd4491dd8112d70d96d73f8f1d12b58cb42fe1bd,Update number of expected tables,2018-04-14T15:03:41Z,2018-04-14T15:16:54Z,2946d096d0cdefdc017559e6b57e87658736e843,13ae486343ea6454a93114c6f558ffea2f2c6874,107914493,9599,9599 bf5ec2d61148f9852441934dd206b3b1c07a512f,Updated PyPI link to pypi.org,2018-04-17T02:24:36Z,2018-04-17T02:24:36Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 4f08fc092f59b434c11f77b6fb2d29b3255227e5,Updated news,2017-12-12T16:52:19Z,2017-12-12T16:52:19Z,2946d096d0cdefdc017559e6b57e87658736e843,cd792325681cbad9f663f2879d8b69f1edbb678f,107914493,9599,19864447 e06b0117711ca7c9d6d6865d2bff8525aa11ebf0,"Updated tests Refs #23",2017-11-10T18:43:54Z,2017-11-10T18:43:54Z,2946d096d0cdefdc017559e6b57e87658736e843,2946d096d0cdefdc017559e6b57e87658736e843,107914493,9599,9599