Bladeren bron

flatfile fixed

George S. Baugh 4 jaren geleden
bovenliggende
commit
6578513a8e
7 gewijzigde bestanden met toevoegingen van 40 en 42 verwijderingen
  1. 1 1
      config/default.cfg
  2. 6 2
      lib/TCMS.pm
  3. 2 11
      lib/Trog/Data/FlatFile.pm
  4. 1 0
      lib/Trog/DataModule.pm
  5. 17 17
      lib/Trog/Routes/HTML.pm
  6. 6 7
      lib/Trog/SQLite/TagIndex.pm
  7. 7 4
      schema/flatfile.schema

+ 1 - 1
config/default.cfg

@@ -1,3 +1,3 @@
 [general]
-    data_model=DUMMY
+    data_model=FlatFile
     title=tCMS

+ 6 - 2
lib/TCMS.pm

@@ -164,8 +164,12 @@ sub app {
     $query->{social_meta}  = 1;
     $query->{primary_post} = {};
 
-    my $output =  $routes{$path}{callback}->($query, \&_render);
-    return $output;
+    #XXX there is a trick to now use strict refs, but I don't remember it right at the moment
+    {
+        no strict 'refs';
+        my $output = $routes{$path}{callback}->($query, \&_render);
+        return $output;
+    }
 };
 
 sub _serve ($path, $streaming=0, $last_fetch=0, $deflate=0) {

+ 2 - 11
lib/Trog/Data/FlatFile.pm

@@ -97,7 +97,8 @@ sub write($self,$data) {
             $update = [(@$parsed, $post)];
         }
 
-        open(my $fh, '>', $file) or confess;
+        mkdir $datastore;
+        open(my $fh, '>', $file) or confess "Could not open $file";
         print $fh $parser->encode($update);
         close $fh;
 
@@ -110,16 +111,6 @@ sub count ($self) {
     return scalar(@index);
 }
 
-sub add ($self,@posts) {
-    my $ctime = time();
-    @posts = map {
-        $_->{id} //= $ctime;
-        $_->{created} = $ctime;
-        $_
-    } @posts;
-    return $self->SUPER::add(@posts);
-}
-
 sub delete($self, @posts) {
     foreach my $update (@posts) {
         unlink "$datastore/$update->{id}" or confess;

+ 1 - 0
lib/Trog/DataModule.pm

@@ -235,6 +235,7 @@ sub add ($self, @posts) {
     foreach my $post (@posts) {
         $post->{id} //= UUID::Tiny::create_uuid_as_string(UUID::Tiny::UUID_V1, UUID::Tiny::UUID_NS_DNS);
         $post->{local_href} //= "/posts/$post->{id}";
+        $post->{method}     //= 'GET';
         $post->{created} = time();
         my @existing_posts = $self->get( id => $post->{id} );
         if (@existing_posts) {

+ 17 - 17
lib/Trog/Routes/HTML.pm

@@ -397,25 +397,8 @@ sub login ($query, $render_cb) {
             # Add a stub user page and the initial series.
             my $dat = Trog::Data->new($conf);
             _setup_initial_db($dat,$query->{username});
-            $dat->add({
-                title      => $query->{username},
-                data       => 'Default user',
-                preview    => '/img/avatar/humm.gif',
-                wallpaper  => '/img/sys/testpattern.jpg',
-                tags       => ['about'],
-                visibility => 'public',
-                acls       => ['admin'],
-                local_href => "/users/$query->{username}",
-                callback   => "Trog::Routes::HTML::users",
-                user       => $query->{username},
-                form       => 'profile.tx',
-            });
             # Ensure we stop registering new users
             File::Touch::touch("config/has_users");
-
-            #hup the parent to refresh the routing table
-            my $parent = getppid;
-            kill 'HUP', $parent;
         }
 
         $query->{failed} = 1;
@@ -449,6 +432,7 @@ sub _setup_initial_db ($dat, $user) {
             "aclname"    => "series",
             "acls"       => [],
             "callback"   => "Trog::Routes::HTML::series",
+            method       => 'GET',
             "data"       => "Series",
             "href"       => "/series",
             "local_href" => "/series",
@@ -464,6 +448,7 @@ sub _setup_initial_db ($dat, $user) {
             "aclname"    => "about",
             "acls"       => [],
             "callback"   => "Trog::Routes::HTML::series",
+            method       => 'GET',
             "data"       => "About",
             "href"       => "/about",
             "local_href" => "/about",
@@ -479,6 +464,7 @@ sub _setup_initial_db ($dat, $user) {
             "aclname"      => "admin",
             acls           => [],
             "callback"     => "Trog::Routes::HTML::config",
+            'method'       => 'GET',
             "content_type" => "text/plain",
             "data"         => "Config",
             "href"         => "/config",
@@ -489,6 +475,20 @@ sub _setup_initial_db ($dat, $user) {
             "title"        => "Configure tCMS",
             user           => $user,
         },
+        {
+            title      => $user,
+            data       => 'Default user',
+            preview    => '/img/avatar/humm.gif',
+            wallpaper  => '/img/sys/testpattern.jpg',
+            tags       => ['about'],
+            visibility => 'public',
+            acls       => ['admin'],
+            local_href => "/users/$user",
+            callback   => "Trog::Routes::HTML::users",
+            method     => 'GET',
+            user       => $user,
+            form       => 'profile.tx',
+        },
     );
 }
 

+ 6 - 7
lib/Trog/SQLite/TagIndex.pm

@@ -11,7 +11,7 @@ use Trog::SQLite;
 
 =head1 Trog::SQLite::TagIndex
 
-An SQLite3 index of posts by tag.
+An SQLite3 index of posts by tag and date.
 Used to speed up the flat-file data model.
 
 Also used to retrieve cached routes from posts.
@@ -23,7 +23,7 @@ Also used to retrieve cached routes from posts.
 sub posts_for_tags (@tags) {
     my $dbh = _dbh();
     my $clause = @tags ? "WHERE tag IN (".join(',' ,(map {'?'} @tags)).")" : '';
-    my $rows = $dbh->selectall_arrayref("SELECT DISTINCT id FROM posts $clause ORDER BY ID DESC",{ Slice => {} }, @tags);
+    my $rows = $dbh->selectall_arrayref("SELECT DISTINCT id FROM posts $clause ORDER BY created DESC",{ Slice => {} }, @tags);
     return () unless ref $rows eq 'ARRAY' && @$rows;
     return map { $_->{id} } @$rows;
 }
@@ -57,9 +57,9 @@ sub build_index($data_obj,$posts=[]) {
     my $t = $dbh->selectall_hashref("SELECT id,name FROM tag", 'name');
     foreach my $k (keys(%$t)) { $t->{$k} = $t->{$k}->{id} };
 
-    Trog::SQLite::bulk_insert($dbh,'posts_index',[qw{post_id tag_id}], 'IGNORE', map {
+    Trog::SQLite::bulk_insert($dbh,'posts_index',[qw{post_id post_time tag_id}], 'IGNORE', map {
         my $subj = $_;
-        map { ( $subj->{id}, $t->{$_} ) } @{$subj->{tags}}
+        map { ( $subj->{id}, $subj->{created}, $t->{$_} ) } @{$subj->{tags}}
     } @$posts );
 }
 
@@ -68,9 +68,8 @@ sub build_routes($data_obj,$posts=[]) {
     my $dbh = _dbh();
     $posts = $data_obj->get({ limit => 0, acls => ['admin'] }) unless @$posts;
 
-    # Ensure the methods & callbacks we need are installed
-    Trog::SQLite::bulk_insert($dbh,'methods',   [qw{method}],   'IGNORE', (uniq map { $_->{method} }   @posts) ); 
-    Trog::SQLite::bulk_insert($dbh,'callbacks', [qw{callback}], 'IGNORE', (uniq map { $_->{callback} } @posts) ); 
+    # Ensure the callbacks we need are installed
+    Trog::SQLite::bulk_insert($dbh,'callbacks', [qw{callback}], 'IGNORE', (uniq map { $_->{callback} } @$posts) );
 
     my $m = $dbh->selectall_hashref("SELECT id, method FROM methods", 'method');
     foreach my $k (keys(%$m)) { $m->{$k} = $m->{$k}->{id} };

+ 7 - 4
schema/flatfile.schema

@@ -4,13 +4,14 @@ CREATE TABLE IF NOT EXISTS tag (
 );
 
 CREATE TABLE IF NOT EXISTS posts_index (
-    post_id INTEGER NOT NULL,
+    post_id TEXT NOT NULL,
+    post_time INTEGER NOT NULL,
     tag_id INTEGER NOT NULL REFERENCES tag(id) ON DELETE CASCADE
 );
 
 CREATE INDEX IF NOT EXISTS tag_idx ON tag(name);
 
-CREATE VIEW IF NOT EXISTS posts AS SELECT p.post_id as id, t.name AS tag FROM posts_index AS p JOIN tag AS t ON t.id=p.tag_id;
+CREATE VIEW IF NOT EXISTS posts AS SELECT p.post_id AS id, p.post_time AS created, t.name AS tag FROM posts_index AS p JOIN tag AS t ON t.id=p.tag_id;
 
 /* The intention is to read this entirely into memory at app startup     */
 /* This should not incur significant costs, even with millions of posts. */
@@ -24,13 +25,15 @@ CREATE TABLE IF NOT EXISTS routes (
 /* TODO  ^^^ */
 CREATE TABLE IF NOT EXISTS methods (
     id INTEGER PRIMARY KEY AUTOINCREMENT,
-    method TEXT NOT NULL
+    method TEXT NOT NULL UNIQUE
 );
 
 CREATE TABLE IF NOT EXISTS callbacks (
     id INTEGER PRIMARY KEY AUTOINCREMENT,
-    callback TEXT NOT NULL
+    callback TEXT NOT NULL UNIQUE
 );
 
 CREATE VIEW IF NOT EXISTS all_routes AS SELECT r.route AS route, m.method AS method, c.callback AS callback FROM routes AS r JOIN methods AS m ON m.id=r.method_id JOIN callbacks AS c ON c.id=r.callback_id;
 
+/* Fill the methods table with the HTTP verbs */
+INSERT OR IGNORE INTO methods (method) VALUES ('GET'),('POST'),('DELETE'),('PUT'),('HEAD'),('PATCH'),('CONNECT'),('OPTIONS'),('TRACE');