You can subscribe to this list here.
2002 |
Jan
|
Feb
(32) |
Mar
(7) |
Apr
(43) |
May
(30) |
Jun
(22) |
Jul
(10) |
Aug
(14) |
Sep
(58) |
Oct
(18) |
Nov
(1) |
Dec
(34) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
(56) |
Feb
|
Mar
(9) |
Apr
(3) |
May
(17) |
Jun
(1) |
Jul
(7) |
Aug
(2) |
Sep
(3) |
Oct
(4) |
Nov
(1) |
Dec
|
2004 |
Jan
|
Feb
|
Mar
(22) |
Apr
(7) |
May
(2) |
Jun
(8) |
Jul
(6) |
Aug
|
Sep
(3) |
Oct
|
Nov
|
Dec
(22) |
2005 |
Jan
(2) |
Feb
|
Mar
|
Apr
|
May
(6) |
Jun
|
Jul
(2) |
Aug
(17) |
Sep
(2) |
Oct
(5) |
Nov
|
Dec
(2) |
2006 |
Jan
|
Feb
(1) |
Mar
(21) |
Apr
(20) |
May
(41) |
Jun
(7) |
Jul
(35) |
Aug
(1) |
Sep
(14) |
Oct
(5) |
Nov
(7) |
Dec
(28) |
2007 |
Jan
(9) |
Feb
(3) |
Mar
(22) |
Apr
(8) |
May
(20) |
Jun
(12) |
Jul
(12) |
Aug
(3) |
Sep
(1) |
Oct
(2) |
Nov
(7) |
Dec
|
2008 |
Jan
(4) |
Feb
(1) |
Mar
(5) |
Apr
(4) |
May
|
Jun
(8) |
Jul
(7) |
Aug
(2) |
Sep
(1) |
Oct
(4) |
Nov
|
Dec
|
2009 |
Jan
(12) |
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: paul_the_nomad <pau...@us...> - 2009-02-11 23:20:43
|
Hello all, On Friday 30 January 2009 21:31:33 chromatic wrote: > On Friday 23 January 2009 09:43:51 paul_the_nomad wrote: > > When, chromatic did his original changes for the OnLamp articles, he > > changed the copyright notice to 2003. But this doesn't make much sense > > because Everything Development corporation didn't exist. My guess is that > > these changes are actually copyright chromatic. > > I'm happy to assign my changes to anyone willing to give them a good home. > Thanks chromatic. I think the best thing to do is speak to the people at Savanah and see what they think. And on a different matter: I've set up a git repository here for anyone who is interested: git://github.com/pault/omnia.git Thanks Paul |
From: chromatic <chr...@wg...> - 2009-01-30 22:54:22
|
On Friday 23 January 2009 09:43:51 paul_the_nomad wrote: > When, chromatic did his original changes for the OnLamp articles, he > changed the copyright notice to 2003. But this doesn't make much sense > because Everything Development corporation didn't exist. My guess is that > these changes are actually copyright chromatic. I'm happy to assign my changes to anyone willing to give them a good home. -- c |
From: Petruchio <pet...@pe...> - 2009-01-27 00:15:25
|
First off, I think you should fork, rename, or fillet the project as you see fit... and I doubt anyone would disagree. You've been laboring in the wilderness on this for a long time, now; why you should feel constrained by the opinions of others (even if you were receiving any), I have no idea. > > On Jan 9, 2009, at 4:31 AM, pau...@us... wrote: > > > >> POINT TWO > >> ========= > >> > >> I'm not sure there's any point posting to this list any more, because > >> I get barely any response and never any assistance .... then some > >> smartarse wonders why things are going so slowly.... > >> > >> Nonetheless, I'd really like to create enthusiasm for everydevel. It is > >> afterall one of the few CMS which are perl based in a world where PHP > >> rules in the space. Not only are there few CMSes in Perl, there are few application in Perl. Perl people tend not to write end-user software; they write libraries, and they tinker with other people's libraries. PHP people, on the other hand, write applications, and have a wonderful attention to detail. One is inclined to say that this is because details are all most of them understand, but it's important to keep in mind that they're succeeding admirably even so. > >> The question is how to create this enthusiasm and where. > >> > >> Experience suggests it isn't here. But where? IMO, you put your finger on it here: > As for being better than Drupal, I actually think Everything is already > better in the fact it is far more flexible. Drupal is easier for > novices to get up and running with though. I think that to make this project popular would require a radical change in direction. Installation is unquestionably the biggest issue. Requiring Apache configuration or mod_perl is death. Even requiring shell access to get the thing running is unacceptable. If you got this to be as easy to install as WordPress, I think you'd find it was all downhill from there, and that popularity came easily. I also think it's very important that something like this look very pretty by default, and that it make it as easy as possible for the average user to do average-user tasks without configuration. But if you made it simple to install, you'd probably get other people to help with those goals. Where I think a CMS could kick the opposition's collective ass would be in fully automating the installation of updates, themes, and plugins. But architectural features don't matter much until there are users. That having been said, I can't say I'll be much help even if you take up my suggestions. But I admire your tenacity, and wish you well. -- Petruchio |
From: Nate O. <noo...@co...> - 2009-01-23 18:35:23
|
Honestly, just go ahead and assign the copyright however you want -- if we need to xfer it from Blockstackers I can handle that, either by getting us to assign copyright to me personally or whatever. IIRC under artistic the copyright is on the code AS the everything engine. Someone else can take the code call it "my cool webframework" and have a copyright on that. --n paul_the_nomad wrote: > On Friday 23 January 2009 17:08:01 Nathan Oostendorp wrote: > >> copyright probably should just get moved to Blockstackers >> >> --n >> > > > Hmmm, this makes it complicated. > > When, chromatic did his original changes for the OnLamp articles, he changed > the copyright notice to 2003. But this doesn't make much sense because > Everything Development corporation didn't exist. My guess is that these > changes are actually copyright chromatic. > > My changes couldn't be assigned to Everything Development because a) it didn't > exist and b) I didn't agree to assign my copyright. > > The reason I'm asking is that if I host a fork at Savannah or gna.org they are > very particular about a clean copyright. > > Do you know how I can contact blockstackers to ask someone about it? > > Thanks > > Paul > > ------------------------------------------------------------------------------ > This SF.net email is sponsored by: > SourcForge Community > SourceForge wants to tell your story. > http://p.sf.net/sfu/sf-spreadtheword > _______________________________________________ > Everydevel-opers mailing list > Eve...@li... > https://lists.sourceforge.net/lists/listinfo/everydevel-opers > |
From: paul_the_nomad <pau...@us...> - 2009-01-23 17:43:57
|
On Friday 23 January 2009 17:08:01 Nathan Oostendorp wrote: > copyright probably should just get moved to Blockstackers > > --n Hmmm, this makes it complicated. When, chromatic did his original changes for the OnLamp articles, he changed the copyright notice to 2003. But this doesn't make much sense because Everything Development corporation didn't exist. My guess is that these changes are actually copyright chromatic. My changes couldn't be assigned to Everything Development because a) it didn't exist and b) I didn't agree to assign my copyright. The reason I'm asking is that if I host a fork at Savannah or gna.org they are very particular about a clean copyright. Do you know how I can contact blockstackers to ask someone about it? Thanks Paul |
From: Nathan O. <noo...@co...> - 2009-01-23 17:08:11
|
copyright probably should just get moved to Blockstackers --n On Jan 23, 2009, at 11:26 AM, paul_the_nomad wrote: > On Friday 23 January 2009 15:55:31 Nathan Oostendorp wrote: >> It's been dissolved since 2001, all the assets went back to the >> parent >> company, Blockstackers Intergalactic LLC >> > > Ah, so what does that mean for the copyright notice in the Eveydevel > files? > Should it be changed? Or does the copyright go into limbo? > |
From: paul_the_nomad <pau...@us...> - 2009-01-23 16:26:11
|
On Friday 23 January 2009 15:55:31 Nathan Oostendorp wrote: > It's been dissolved since 2001, all the assets went back to the parent > company, Blockstackers Intergalactic LLC > Ah, so what does that mean for the copyright notice in the Eveydevel files? Should it be changed? Or does the copyright go into limbo? |
From: Nathan O. <noo...@co...> - 2009-01-23 15:55:37
|
It's been dissolved since 2001, all the assets went back to the parent company, Blockstackers Intergalactic LLC --n On Jan 23, 2009, at 7:38 AM, pau...@us... wrote: > Hi Nate, > > Another question. "Everything Development, Inc" sounds like a > registered corporation. Is it still a registered corporation, or > was it > dissolved? > > Cheers, > > Paul > > Nathan Oostendorp wrote: >> Hey Paul, >> >> To address point #2, I agree that this list is pretty dead. I'd >> would >> encourage you to put these someplace public, like on a blog or >> everydevel (of course still sitting under my desk without network >> until >> the bastards at comcast fix our internet connection). This way >> people >> can just reply as they want to, without being list subscribers. >> >> I also think if you're really interested in keeping it alive long >> term >> you should consider "forking" or otherwise re-branding the project >> and >> then either doing regular releases, or making it a micro-packaged >> SVN-distributed project (ala ruby gems). "Everything Engine" has >> always >> been a kind of an ad-hoc name, and i think most of the people that >> have >> heard of it just associate it with Everything2, which I don't think >> is >> what you're ultimately aiming for. I think you need to reframe the >> fundamental pitch to say "HEY, WE'RE LIKE DRUPAL BUT PERL BUT ALSO >> BETTER BECAUSE WE DO X AND Y AND Z", since CMSs are a dime a dozen >> now. >> >> If there's anything I can do, please let me know. >> >> --n >> >> >> >> >> >> On Jan 9, 2009, at 4:31 AM, pau...@us... >> wrote: >> >>> Hello list, >>> >>> Two points here: >>> >>> POINT ONE >>> ========= >>> >>> The latest thing I've been working on in everydevel is changing the >>> database structure for more normalisation. The good news is that >>> this >>> works. The bad news is that it is taking me longer than I thought >>> partly because I've had to do a lot of thinking and partly because >>> there >>> is no one to bounce ideas off. >>> >>> These changes in the db layer have to have knock on effects. I'll >>> give >>> you an example: permissions. >>> >>> As you know permissions in everydevel have five types r, w, x, d, >>> c and >>> there are four user types for each permission: owner, group, other, >>> guest. >>> >>> After my db redesign it is obvious that this is arbitrary and there >>> could be more permission types and user types. >>> >>> It is also has become obvious that nodes can't continue to 'know' >>> about >>> their own permissions. Because to do so they'd also have to >>> continue to >>> 'know' about any 'usertype' nodes in the nodebase to which they >>> belong. >>> This means that each and every node would have to have some sort of >>> aggregate behaviour as well as their standard behaviour. >>> >>> This of course is waaaay too complicated and indicates a design >>> problem. >>> >>> The solution is to change Security.pm into an object class that >>> negotiates permissions, or perhaps to make Security.pm a nodetype >>> that >>> has the job of negotiating access between the UI and the NodeBase. >>> >>> Anyway, the point is these knock on effects get a bit involved. >>> >>> >>> POINT TWO >>> ========= >>> >>> I'm not sure there's any point posting to this list any more, >>> because >>> I get barely any response and never any assistance .... then some >>> smartarse wonders why things are going so slowly.... >>> >>> Nonetheless, I'd really like to create enthusiasm for everydevel. >>> It is >>> afterall one of the few CMS which are perl based in a world where >>> PHP >>> rules in the space. The question is how to create this enthusiasm >>> and >>> where. >>> >>> Experience suggests it isn't here. But where? >>> >>> Paul >>> >>> ------------------------------------------------------------------------------ >>> >>> Check out the new SourceForge.net Marketplace. >>> It is the best place to buy or sell services for >>> just about anything Open Source. >>> http://p.sf.net/sfu/Xq1LFB >>> _______________________________________________ >>> Everydevel-opers mailing list >>> Eve...@li... >>> https://lists.sourceforge.net/lists/listinfo/everydevel-opers >> >> >> > > ------------------------------------------------------------------------------ > This SF.net email is sponsored by: > SourcForge Community > SourceForge wants to tell your story. > http://p.sf.net/sfu/sf-spreadtheword > _______________________________________________ > Everydevel-opers mailing list > Eve...@li... > https://lists.sourceforge.net/lists/listinfo/everydevel-opers |
From: <pau...@us...>
<pau...@us...> - 2009-01-23 15:11:51
|
Hello anyone who's there, Here's a proposed SQL schema for Everydevel. It's aims are to make nodes more light-weight and make it easier for the platform to be extended. It's postgresql because I knew that using views and rules I could make it transparent to the current code, I'm not sure that mysql and sqlite would allow this flexibility. Other points: Yes it's slow, especially packing and unpacking those permissions, but a new front end model will fix that. Yes, it's complicated, but higher levels of normalisation always involve more tables. Constructive thoughts? Paul CREATE TABLE "node_relation_type" ( name varchar(125) UNIQUE NOT NULL, description text, node_relation_type_pk serial, PRIMARY KEY ( "node_relation_type_pk" ) ) ; CREATE INDEX index_node_relation_type ON node_relation_type ( name ) ; CREATE AGGREGATE textcat_all( basetype = text, sfunc = textcat, stype = text, initcond = '' ); CREATE TABLE "node_basic" ( node_id bigserial UNIQUE NOT NULL, type_nodetype bigint, createtime timestamp NOT NULL, PRIMARY KEY (node_id) ); CREATE TABLE "node_relationship" ( node bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, hasa_node bigint REFERENCES node_basic(node_id) ON DELETE RESTRICT, relation_type int REFERENCES node_relation_type( node_relation_type_pk) ON DELETE RESTRICT, PRIMARY KEY ("node", "hasa_node", "relation_type") ) ; CREATE TABLE "sqltable_type" ( sqltable_type varchar(255) NOT NULL, description varchar(255), sqltable_type_pk serial, PRIMARY KEY ( "sqltable_type_pk" ) ) ; CREATE TABLE "sqltable" ( sqltable_name varchar(255) NOT NULL UNIQUE, type int REFERENCES sqltable_type(sqltable_type_pk) ON DELETE RESTRICT, sqltable_pk bigserial NOT NULL, PRIMARY KEY ( sqltable_pk ) ) ; CREATE TABLE "node_sqltable" ( sqltable bigint REFERENCES sqltable(sqltable_pk), nodetype_id bigint REFERENCES node_basic(node_id), node_sqltable_pk serial NOT NULL, UNIQUE (sqltable, nodetype_id), PRIMARY KEY ( node_sqltable_pk ) ) ; CREATE TABLE "nodegroup_restrict_type"( group_nodetype_id bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, only_nodetype bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, PRIMARY KEY( group_nodetype_id, only_nodetype ) ) ; CREATE TABLE "nodebase_restrictdupes" ( nodetype_id bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, PRIMARY KEY (nodetype_id) ) ; CREATE TABLE "nodebase_node_workspace" ( node_id bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, enable boolean NOT NULL, PRIMARY KEY (node_id) ) ; CREATE TABLE "nodebase_node_revisions" ( node_id bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, maxrevisions int DEFAULT 0 NOT NULL, PRIMARY KEY (node_id) ) ; CREATE TABLE "node_modified" ( modified timestamp, node_id bigint NOT NULL REFERENCES node_basic(node_id) ON DELETE CASCADE, PRIMARY KEY (node_id) ) ; CREATE TABLE "node_title" ( title varchar(240), node_id bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, PRIMARY KEY (node_id) ) ; CREATE TABLE "node_statistics_hits" ( hits bigint NOT NULL DEFAULT 0, node_id bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, PRIMARY KEY (node_id) ) ; CREATE TABLE "node_location" ( loc_location bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, node_id bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, PRIMARY KEY (node_id) ) ; CREATE TABLE "node_statistics_reputation" ( reputation bigint NOT NULL DEFAULT 0, node_id bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, PRIMARY KEY (node_id) ) ; CREATE TABLE "node_lock" ( locktime timestamp NOT NULL, lockby_user bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, node_id bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, PRIMARY KEY (node_id) ) ; CREATE TABLE "user_type" ( user_type_pk serial NOT NULL, usertype varchar(32) NOT NULL, description varchar(255), PRIMARY KEY ("user_type_pk") ) ; CREATE TABLE "permission_type" ( permission_type_pk serial NOT NULL, permission varchar(127) NOT NULL, description varchar(255), PRIMARY KEY("permission_type_pk") ) ; CREATE TABLE "permission_behaviour" ( permission_behaviour_pk serial NOT NULL, behaviour varchar(10) NOT NULL, description varchar(255), PRIMARY KEY ("permission_behaviour_pk") ) ; CREATE TABLE "node_authorisation" ( permission_type int REFERENCES permission_type(permission_type_pk) ON DELETE RESTRICT NOT NULL, permission_behaviour int REFERENCES permission_behaviour(permission_behaviour_pk) ON DELETE RESTRICT NOT NULL, node_id bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, PRIMARY KEY (permission_type, node_id, permission_behaviour) ) ; CREATE TABLE "node_access" ( user_type int REFERENCES user_type(user_type_pk) ON DELETE RESTRICT NOT NULL, permission_type int REFERENCES permission_type(permission_type_pk) ON DELETE RESTRICT NOT NULL, permission_behaviour int REFERENCES permission_behaviour(permission_behaviour_pk) ON DELETE RESTRICT NOT NULL, node_id bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, PRIMARY KEY (user_type, permission_type, node_id, permission_behaviour) ) ; CREATE TABLE "node_dynamicpermission" ( type int REFERENCES user_type (user_type_pk) ON DELETE RESTRICT, permission bigint REFERENCES node_basic(node_id) ON DELETE RESTRICT, node_id bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, PRIMARY KEY (type, node_id) ) ; CREATE TABLE "node_relationship_usertype" ( node bigint REFERENCES node_basic(node_id) ON DELETE CASCADE, with_node bigint REFERENCES node_basic(node_id) ON DELETE RESTRICT, relation_type int REFERENCES node_relation_type( node_relation_type_pk) ON DELETE RESTRICT, user_type int REFERENCES user_type(user_type_pk) ON DELETE RESTRICT, PRIMARY KEY ("node", "with_node", "relation_type", "user_type") ) ; CREATE FUNCTION dynamicpermission ( bigint, text ) RETURNS bigint AS $$ SELECT permission FROM node_dynamicpermission WHERE type = ( SELECT user_type.user_type_pk FROM user_type WHERE user_type.usertype = $2) AND node_id = $1; $$ LANGUAGE SQL; ; CREATE OR REPLACE FUNCTION nodepermissions(bigint, varchar) RETURNS text AS $$ SELECT CASE ( SELECT permission_behaviour.behaviour from node_access, user_type, permission_type, permission_behaviour where permission_type.permission = 'read' AND node_access.node_id = $1 AND user_type.usertype = $2 AND node_access.user_type = user_type.user_type_pk AND node_access.permission_behaviour = permission_behaviour.permission_behaviour_pk AND node_access.permission_type = permission_type.permission_type_pk) WHEN 'enable' THEN 'r' WHEN 'disable' THEN '-' WHEN 'inherit' THEN 'i' END || CASE ( SELECT permission_behaviour.behaviour from node_access, user_type, permission_type, permission_behaviour where permission_type.permission = 'write' AND node_access.node_id = $1 AND user_type.usertype = $2 AND node_access.user_type = user_type.user_type_pk AND node_access.permission_behaviour = permission_behaviour.permission_behaviour_pk AND node_access.permission_type = permission_type.permission_type_pk) WHEN 'enable' THEN 'w' WHEN 'disable' THEN '-' WHEN 'inherit' THEN 'i' END || CASE ( SELECT permission_behaviour.behaviour from node_access, user_type, permission_type, permission_behaviour where permission_type.permission = 'execute' AND node_access.node_id = $1 AND user_type.usertype = $2 AND node_access.user_type = user_type.user_type_pk AND node_access.permission_behaviour = permission_behaviour.permission_behaviour_pk AND node_access.permission_type = permission_type.permission_type_pk) WHEN 'enable' THEN 'x' WHEN 'disable' THEN '-' WHEN 'inherit' THEN 'i' END || CASE ( SELECT permission_behaviour.behaviour from node_access, user_type, permission_type, permission_behaviour where permission_type.permission = 'delete' AND node_access.node_id = $1 AND user_type.usertype = $2 AND node_access.user_type = user_type.user_type_pk AND node_access.permission_behaviour = permission_behaviour.permission_behaviour_pk AND node_access.permission_type = permission_type.permission_type_pk) WHEN 'enable' THEN 'd' WHEN 'disable' THEN '-' WHEN 'inherit' THEN 'i' END || CASE WHEN $2 = 'author' OR $2 = 'defaultauthor' THEN '' ELSE ( CASE ( SELECT permission_behaviour.behaviour from node_access, user_type, permission_type, permission_behaviour where permission_type.permission = 'create' AND node_access.node_id = $1 AND user_type.usertype = $2 AND node_access.user_type = user_type.user_type_pk AND node_access.permission_behaviour = permission_behaviour.permission_behaviour_pk AND node_access.permission_type = permission_type.permission_type_pk) WHEN 'enable' THEN 'c' WHEN 'disable' THEN '-' WHEN 'inherit' THEN 'i' END) END; $$ LANGUAGE SQL; ; CREATE FUNCTION "related_node_id" ( bigint, varchar ) RETURNS bigint AS $$ SELECT node_relationship.hasa_node FROM node_relationship, node_relation_type WHERE node_relationship.node = $1 AND node_relationship.relation_type = node_relation_type_pk AND node_relation_type.name = $2 $$ LANGUAGE SQL; ; CREATE TABLE "attribute_type" ( name varchar(125) UNIQUE NOT NULL, description varchar(255), attribute_type_pk serial, PRIMARY KEY ("attribute_type_pk") ) ; CREATE TABLE "timestamp_attribute" ( time timestamp NOT NULL, node bigint REFERENCES node_basic( node_id) ON DELETE CASCADE, PRIMARY KEY ("node") ) ; CREATE VIEW "node" AS SELECT node_basic.node_id AS node_id, node_basic.type_nodetype, node_basic.createtime, related_node_id( node_basic.node_id, 'author_user') AS author_user, node_title.title, node_modified.modified, node_statistics_hits.hits, related_node_id( node_basic.node_id, 'loc_location') AS loc_location, node_statistics_reputation.reputation, node_lock.locktime, node_lock.lockby_user, nodepermissions( node_basic.node_id, 'author') AS authoraccess, nodepermissions( node_basic.node_id, 'group') AS groupaccess, nodepermissions( node_basic.node_id, 'other') AS otheraccess, nodepermissions( node_basic.node_id, 'guest') AS guestaccess, dynamicpermission( node_basic.node_id, 'author' ) as dynamicauthor_permission, dynamicpermission( node_basic.node_id, 'group' ) as dynamicgroup_permission, dynamicpermission( node_basic.node_id, 'other' ) as dynamicother_permission, dynamicpermission( node_basic.node_id, 'guest' ) as dynamicguest_permission, related_node_id( node_basic.node_id, 'group_usergroup') AS group_usergroup FROM node_basic LEFT JOIN node_modified ON node_modified.node_id = node_basic.node_id LEFT JOIN node_title ON node_basic.node_id = node_title.node_id LEFT JOIN node_statistics_hits ON node_basic.node_id = node_statistics_hits.node_id LEFT JOIN node_statistics_reputation ON node_basic.node_id = node_statistics_reputation.node_id LEFT JOIN node_lock ON node_basic.node_id = node_lock.node_id ; ; CREATE FUNCTION select_sqltables_nodetype( bigint, text ) RETURNS varchar AS $$ DECLARE node_id ALIAS FOR $1; tabletype ALIAS FOR $2; tablename varchar; tablelist varchar := ''; BEGIN FOR tablename IN SELECT sqltable.sqltable_name FROM sqltable, sqltable_type, node_sqltable WHERE node_sqltable.nodetype_id = node_id AND node_sqltable.sqltable = sqltable.sqltable_pk AND sqltable.type = sqltable_type_pk AND sqltable_type.sqltable_type = tabletype LOOP IF tablelist <> '' THEN tablelist := tablelist || ',' || tablename; ELSE tablelist := tablename; END IF; END LOOP; RETURN tablelist; END; $$ LANGUAGE plpgsql ; CREATE VIEW "nodetype" AS SELECT node_basic.node_id AS nodetype_id, related_node_id( node_basic.node_id, 'restrict_nodetype' ) AS restrict_nodetype, related_node_id( node_basic.node_id, 'extends_nodetype' ) AS extends_nodetype, ( SELECT (CASE ( SELECT b.behaviour FROM node_authorisation a, permission_type t, permission_behaviour b WHERE a.node_id = node_basic.node_id AND a.permission_type = t.permission_type_pk AND t.permission = 'restrictdupes' AND a.permission_behaviour = b.permission_behaviour_pk ) WHEN 'enable' THEN 1 WHEN 'disable' THEN 0 WHEN 'inherit' THEN -1 END ) ) AS restrictdupes, ( SELECT select_sqltables_nodetype( node_basic.node_id, 'attributetable' ) ) AS sqltable, ( SELECT select_sqltables_nodetype( node_basic.node_id, 'grouptable' ) ) AS grouptable, nodepermissions( node_basic.node_id, 'defaultauthor' ) AS defaultauthoraccess, nodepermissions( node_basic.node_id, 'defaultgroup' ) AS defaultgroupaccess, nodepermissions( node_basic.node_id, 'defaultother' ) AS defaultotheraccess, nodepermissions( node_basic.node_id, 'defaultguest' ) AS defaultguestaccess, related_node_id( node_basic.node_id, 'defaultgroup_usergroup') AS defaultgroup_usergroup, dynamicpermission ( node_basic.node_id, 'defaultauthor') AS defaultauthor_permission, dynamicpermission ( node_basic.node_id, 'defaultgroup') AS defaultgroup_permission, dynamicpermission ( node_basic.node_id, 'defaultother') AS defaultother_permission, dynamicpermission ( node_basic.node_id, 'defaultguest') AS defaultguest_permission, ( SELECT maxrevisions FROM nodebase_node_revisions r WHERE r.node_id = node_basic.node_id ) AS maxrevisions, ( SELECT (CASE ( SELECT b.behaviour FROM node_authorisation a, permission_type t, permission_behaviour b WHERE a.node_id = node_basic.node_id AND a.permission_type = t.permission_type_pk AND t.permission = 'canworkspace' AND a.permission_behaviour = b.permission_behaviour_pk ) WHEN 'enable' THEN 1 WHEN 'disable' THEN 0 WHEN 'inherit' THEN -1 END ) ) AS canworkspace FROM node_basic LEFT JOIN nodegroup_restrict_type ON nodegroup_restrict_type.group_nodetype_id = node_basic.node_id LEFT JOIN nodebase_restrictdupes ON nodebase_restrictdupes.nodetype_id = node_basic.node_id WHERE type_nodetype = 1; ; CREATE OR REPLACE FUNCTION insert_permissions (bigint, text, text) RETURNS VOID AS $$ INSERT INTO node_access ( node_id, user_type, permission_type, permission_behaviour ) SELECT $1, user_type.user_type_pk, permission_type.permission_type_pk, permission_behaviour.permission_behaviour_pk FROM user_type, permission_type, permission_behaviour WHERE permission_type.permission = 'read' AND user_type.usertype = $2 AND permission_behaviour.behaviour = CASE substring( $3 from 1 for 1 ) WHEN 'r' THEN 'enable' WHEN '-' THEN 'disable' WHEN 'i' THEN 'inherit' ELSE NULL END; INSERT INTO node_access ( node_id, user_type, permission_type, permission_behaviour ) SELECT $1, user_type.user_type_pk, permission_type.permission_type_pk, permission_behaviour.permission_behaviour_pk FROM user_type, permission_type, permission_behaviour WHERE permission_type.permission = 'write' AND user_type.usertype = $2 AND permission_behaviour.behaviour = CASE substring( $3 from 2 for 1 ) WHEN 'w' THEN 'enable' WHEN '-' THEN 'disable' WHEN 'i' THEN 'inherit' ELSE NULL END; INSERT INTO node_access ( node_id, user_type, permission_type, permission_behaviour ) SELECT $1, user_type.user_type_pk, permission_type.permission_type_pk, permission_behaviour.permission_behaviour_pk FROM user_type, permission_type, permission_behaviour WHERE permission_type.permission = 'execute' AND user_type.usertype = $2 AND permission_behaviour.behaviour = CASE substring( $3 from 3 for 1 ) WHEN 'x' THEN 'enable' WHEN '-' THEN 'disable' WHEN 'i' THEN 'inherit' ELSE NULL END; INSERT INTO node_access ( node_id, user_type, permission_type, permission_behaviour ) SELECT $1, user_type.user_type_pk, permission_type.permission_type_pk, permission_behaviour.permission_behaviour_pk FROM user_type, permission_type, permission_behaviour WHERE permission_type.permission = 'delete' AND user_type.usertype = $2 AND permission_behaviour.behaviour = CASE substring( $3 from 4 for 1 ) WHEN 'd' THEN 'enable' WHEN '-' THEN 'disable' WHEN 'i' THEN 'inherit' ELSE NULL END; INSERT INTO node_access ( node_id, user_type, permission_type, permission_behaviour ) SELECT $1, user_type.user_type_pk, permission_type.permission_type_pk, permission_behaviour.permission_behaviour_pk FROM user_type, permission_type, permission_behaviour WHERE permission_type.permission = 'create' AND user_type.usertype = $2 AND substring( $3 from 5 for 1 ) <> '' AND permission_behaviour.behaviour = CASE substring( $3 from 5 for 1 ) WHEN 'c' THEN 'enable' WHEN '-' THEN 'disable' WHEN 'i' THEN 'inherit' ELSE NULL END; $$ LANGUAGE SQL; ; CREATE OR REPLACE FUNCTION update_permissions (bigint, text, text) RETURNS VOID AS $$ DELETE FROM node_access WHERE node_access.node_id = $1 AND user_type = ( SELECT user_type.user_type_pk FROM user_type where user_type.usertype = $2 ); SELECT insert_permissions( $1, $2, $3 ); $$ LANGUAGE SQL; ; CREATE FUNCTION insert_node_relation (bigint, bigint, varchar) RETURNS VOID AS $$ INSERT INTO node_relationship (hasa_node, node, relation_type ) SELECT $2, $1, node_relation_type.node_relation_type_pk FROM node_relation_type WHERE node_relation_type.name = $3 AND $2 IS NOT NULL; $$ LANGUAGE SQL; ; CREATE FUNCTION insert_dynamic_permission ( bigint, bigint, varchar ) RETURNS VOID AS $$ --node_id, permission_id, user_type INSERT INTO node_relationship_usertype (node, with_node, relation_type, user_type ) SELECT $1, $2, ( SELECT node_relation_type_pk FROM node_relation_type WHERE name = 'dynamic permission' ), ( SELECT user_type_pk FROM user_type WHERE user_type.usertype = $3) WHERE $2 IS NOT NULL; $$ LANGUAGE SQL; ; CREATE RULE _insert_node AS ON INSERT TO node DO INSTEAD ( INSERT INTO node_basic ( type_nodetype, createtime ) VALUES ( NEW.type_nodetype, now() ); SELECT insert_node_relation( currval('node_basic_node_id_seq'), NEW.author_user, 'author_user' ); INSERT INTO node_title (title, node_id ) SELECT NEW.title, currval('node_basic_node_id_seq') WHERE NEW.title IS NOT NULL; INSERT INTO node_statistics_hits (hits, node_id ) SELECT NEW.hits, currval('node_basic_node_id_seq') WHERE NEW.hits IS NOT NULL; SELECT insert_node_relation ( currval('node_basic_node_id_seq'), NEW.loc_location, 'loc_location' ); INSERT INTO node_statistics_reputation (reputation, node_id ) SELECT NEW.reputation, currval('node_basic_node_id_seq') WHERE NEW.reputation IS NOT NULL; INSERT INTO node_lock (locktime, lockby_user, node_id ) SELECT NEW.locktime, NEW.lockby_user, currval('node_basic_node_id_seq') WHERE NEW.locktime IS NOT NULL; SELECT insert_node_relation( currval('node_basic_node_id_seq'), NEW.group_usergroup, 'group_usergroup' ); SELECT insert_permissions( currval('node_basic_node_id_seq'), 'author', NEW.authoraccess ); SELECT insert_permissions( currval('node_basic_node_id_seq'), 'group', NEW.groupaccess ); SELECT insert_permissions( currval('node_basic_node_id_seq'), 'other', NEW.otheraccess ); SELECT insert_permissions( currval('node_basic_node_id_seq'), 'guest', NEW.guestaccess ); SELECT insert_dynamic_permission( NEW.node_id, NEW.dynamicauthor_permission, 'author' ); SELECT insert_dynamic_permission( NEW.node_id, NEW.dynamicauthor_permission, 'group' ); SELECT insert_dynamic_permission( NEW.node_id, NEW.dynamicauthor_permission, 'other' ); SELECT insert_dynamic_permission( NEW.node_id, NEW.dynamicauthor_permission, 'guest' ); ) ; CREATE FUNCTION update_dynamicpermission (bigint, text, bigint ) RETURNS VOID AS $$ -- node_id, author type, permission_id DELETE FROM node_relationship_usertype WHERE node = $1 AND relation_type = (SELECT node_relation_type_pk FROM node_relation_type WHERE node_relation_type.name = 'dynamic permission' ) AND user_type = ( SELECT user_type_pk FROM user_type WHERE usertype = $2 ) AND $3 IS NULL; UPDATE node_relationship_usertype SET with_node = $3 WHERE node = $1 AND user_type = ( SELECT user_type_pk FROM user_type WHERE user_type.usertype = $2 ) AND relation_type = ( SELECT node_relation_type_pk FROM node_relation_type WHERE node_relation_type.name = 'dynamic permission' ) AND $3 IS NOT NULL AND $3 <> 0; INSERT INTO node_relationship_usertype (with_node, user_type, node, relation_type) SELECT $3, ( SELECT user_type_pk FROM user_type WHERE usertype = $2 ), $1, ( SELECT node_relation_type_pk FROM node_relation_type where name = 'dynamic permission') WHERE $3 IS NOT NULL AND $3 <> 0 AND NOT EXISTS ( SELECT * FROM node_relationship_usertype, user_type, node_relation_type WHERE node_relationship_usertype.node = $1 AND node_relationship_usertype.user_type = ( SELECT user_type.user_type_pk FROM user_type WHERE usertype = $2 ) AND node_relationship_usertype.relation_type = ( SELECT node_relation_type_pk from node_relation_type where name = 'dynamic permission')); $$ LANGUAGE SQL; ; -- First arg is the node_id from. The second is the 'has-a' node. The third is the relationship type. CREATE FUNCTION update_node_relation (bigint, bigint, varchar ) RETURNS VOID AS $$ DELETE FROM node_relationship WHERE $1 = node_relationship.node AND node_relationship.relation_type = ( SELECT node_relation_type.node_relation_type_pk FROM node_relation_type WHERE node_relation_type.name = $3 ) AND $2 IS NULL; UPDATE node_relationship SET hasa_node = $2 WHERE node_relationship.node = $1 AND $2 IS NOT NULL AND node_relationship.relation_type = ( SELECT node_relation_type_pk FROM node_relation_type WHERE node_relation_type.name = $3); INSERT INTO node_relationship (hasa_node, node, relation_type ) SELECT $2, $1, node_relation_type.node_relation_type_pk FROM node_relation_type WHERE node_relation_type.name = $3 AND $2 IS NOT NULL AND NOT EXISTS ( SELECT * FROM node_relationship, node_relation_type WHERE node_relationship.node = $1 AND node_relationship.relation_type = node_relation_type.node_relation_type_pk AND node_relation_type.name = $3 ); $$ LANGUAGE SQL; ; CREATE RULE _update_node AS ON UPDATE TO node DO INSTEAD ( UPDATE node_basic SET type_nodetype = NEW.type_nodetype WHERE NEW.type_nodetype <> OLD.type_nodetype AND NEW.node_id = node_basic.node_id; SELECT update_node_relation( NEW.node_id, NEW.author_user, 'author_user' ); DELETE FROM node_title WHERE NEW.node_id = node_title.node_id AND NEW.title IS NULL; UPDATE node_title SET title = NEW.title WHERE NEW.node_id = node_title.node_id AND NEW.title IS NOT NULL; INSERT INTO node_title (title, node_id) SELECT NEW.title, NEW.node_id WHERE NEW.title IS NOT NULL AND NOT EXISTS ( SELECT * FROM node_title WHERE node_title.node_id = NEW.node_id ); DELETE FROM node_statistics_hits WHERE NEW.node_id = node_statistics_hits.node_id AND NEW.hits IS NULL; UPDATE node_statistics_hits SET hits = NEW.hits WHERE NEW.node_id = node_statistics_hits.node_id; INSERT INTO node_statistics_hits (hits, node_id) SELECT NEW.hits, NEW.node_id WHERE NEW.hits IS NOT NULL AND NOT EXISTS ( SELECT * FROM node_statistics_hits WHERE node_statistics_hits.node_id = NEW.node_id ); SELECT update_node_relation( NEW.node_id, NEW.loc_location, 'loc_location' ); DELETE FROM node_statistics_reputation WHERE NEW.node_id = node_statistics_reputation.node_id AND NEW.reputation IS NULL; UPDATE node_statistics_reputation SET reputation = NEW.reputation WHERE NEW.node_id = node_statistics_reputation.node_id AND NEW.reputation IS NOT NULL; INSERT INTO node_statistics_reputation (reputation, node_id) SELECT NEW.reputation, NEW.node_id WHERE NEW.reputation IS NOT NULL AND NOT EXISTS ( SELECT * FROM node_statistics_reputation WHERE node_statistics_reputation.node_id = NEW.node_id ); DELETE FROM node_lock WHERE NEW.node_id = node_lock.node_id AND ( NEW.locktime IS NULL OR NEW.lockby_user IS NULL ); UPDATE node_lock SET locktime = NEW.locktime, lockby_user = NEW.lockby_user WHERE NEW.node_id = node_lock.node_id AND NEW.locktime IS NOT NULL AND NEW.lockby_user IS NOT NULL; INSERT INTO node_lock (locktime, lockby_user, node_id) SELECT NEW.locktime, NEW.lockby_user, NEW.node_id WHERE NEW.locktime IS NOT NULL AND NEW.lockby_user IS NOT NULL AND NOT EXISTS ( SELECT * FROM node_lock WHERE node_lock.node_id = NEW.node_id ); SELECT update_node_relation( NEW.node_id, NEW.group_usergroup, 'group_usergroup'); SELECT update_dynamicpermission( NEW.node_id, 'author', NEW.dynamicauthor_permission ); SELECT update_dynamicpermission( NEW.node_id, 'group', NEW.dynamicgroup_permission ); SELECT update_dynamicpermission( NEW.node_id, 'other', NEW.dynamicother_permission ); SELECT update_dynamicpermission( NEW.node_id, 'author', NEW.dynamicguest_permission ); SELECT update_permissions( NEW.node_id, 'author', NEW.authoraccess ); SELECT update_permissions( NEW.node_id, 'group', NEW.groupaccess ); SELECT update_permissions( NEW.node_id, 'other', NEW.otheraccess ); SELECT update_permissions( NEW.node_id, 'guest', NEW.guestaccess ); ) ; CREATE RULE _delete_node AS ON DELETE TO node DO INSTEAD ( DELETE FROM node_relationship WHERE node_relationship.node = OLD.node_id; DELETE FROM node_title WHERE node_id = OLD.node_id; DELETE FROM node_statistics_hits WHERE node_id = OLD.node_id; DELETE FROM node_location WHERE node_id = OLD.node_id; DELETE FROM node_statistics_reputation WHERE node_id = OLD.node_id; DELETE FROM node_lock WHERE node_id = OLD.node_id; DELETE FROM node_access WHERE node_id = OLD.node_id; DELETE FROM node_dynamicpermission WHERE node_id = OLD.node_id; DELETE FROM node_basic WHERE node_id = OLD.node_id; ) ; CREATE OR REPLACE FUNCTION split_on_comma(text) RETURNS SETOF varchar AS $$ DECLARE index INTEGER := 1; tablename varchar; BEGIN IF $1 IS NULL THEN RETURN; END IF; LOOP tablename := split_part( $1, ',',index ); IF tablename = '' THEN EXIT; END IF; index := index + 1; RETURN NEXT tablename; END LOOP; RETURN; END; $$ LANGUAGE plpgsql ; CREATE FUNCTION insert_sqltable_data( text, text, bigint ) RETURNS VOID AS $$ DECLARE tablelist ALIAS FOR $1; tabletype ALIAS FOR $2; node_id ALIAS FOR $3; tablename varchar; BEGIN FOR tablename IN SELECT * FROM split_on_comma( tablelist ) LOOP INSERT INTO sqltable (sqltable_name, type ) SELECT tablename, sqltable_type_pk FROM sqltable_type WHERE sqltable_type.sqltable_type = tabletype AND NOT EXISTS ( SELECT * FROM sqltable WHERE sqltable.sqltable_name = tablename ); INSERT INTO node_sqltable (nodetype_id, sqltable) SELECT node_id, sqltable_pk FROM sqltable WHERE sqltable_name = tablename AND NOT EXISTS ( SELECT * FROM node_sqltable, sqltable_type, sqltable WHERE node_sqltable.nodetype_id = node_id AND node_sqltable.sqltable = sqltable.sqltable_pk and sqltable.type = sqltable_type.sqltable_type_pk and sqltable_type.sqltable_type = tabletype AND sqltable.sqltable_name = tablename); END LOOP; RETURN; END; $$ LANGUAGE plpgsql ; CREATE RULE _insert_nodetype AS ON INSERT TO nodetype DO INSTEAD ( SELECT insert_node_relation( NEW.nodetype_id, NEW.restrict_nodetype, 'restrict_nodetype'); SELECT insert_node_relation( NEW.nodetype_id, NEW.extends_nodetype, 'extends_nodetype') WHERE NEW.extends_nodetype <> 0; INSERT INTO node_authorisation ( node_id, permission_type, permission_behaviour ) SELECT NEW.nodetype_id, permission_type.permission_type_pk, permission_behaviour.permission_behaviour_pk FROM permission_type, permission_behaviour WHERE permission_type.permission = 'restrictdupes' AND permission_behaviour.behaviour = CASE NEW.restrictdupes WHEN '1' THEN 'enable' WHEN '0' THEN 'disable' WHEN '-1' THEN 'inherit' ELSE NULL END; SELECT insert_sqltable_data( NEW.sqltable, 'attributetable', NEW.nodetype_id ); SELECT insert_sqltable_data( NEW.grouptable, 'grouptable', NEW.nodetype_id ); SELECT insert_permissions( NEW.nodetype_id, 'defaultauthor', NEW.defaultauthoraccess ); SELECT insert_permissions( NEW.nodetype_id, 'defaultgroup', NEW.defaultgroupaccess ); SELECT insert_permissions( NEW.nodetype_id, 'defaultother', NEW.defaultotheraccess ); SELECT insert_permissions( NEW.nodetype_id, 'defaultguest', NEW.defaultguestaccess ); SELECT insert_node_relation( NEW.nodetype_id, NEW.defaultgroup_usergroup, 'defaultgroup_usergroup' ); SELECT insert_dynamic_permission ( NEW.nodetype_id, NEW.defaultauthor_permission, 'defaultauthor' ); SELECT insert_dynamic_permission ( NEW.nodetype_id, NEW.defaultgroup_permission, 'defaultgroup' ); SELECT insert_dynamic_permission ( NEW.nodetype_id, NEW.defaultother_permission, 'defaultother' ); SELECT insert_dynamic_permission ( NEW.nodetype_id, NEW.defaultguest_permission, 'defaultguest' ); INSERT INTO nodebase_node_revisions (node_id, maxrevisions) SELECT NEW.nodetype_id, NEW.maxrevisions WHERE NEW.maxrevisions IS NOT NULL; INSERT INTO node_authorisation ( node_id, permission_type, permission_behaviour ) SELECT NEW.nodetype_id, permission_type.permission_type_pk, permission_behaviour.permission_behaviour_pk FROM permission_type, permission_behaviour WHERE permission_type.permission = 'canworkspace' AND permission_behaviour.behaviour = CASE NEW.canworkspace WHEN '1' THEN 'enable' WHEN '0' THEN 'disable' WHEN '-1' THEN 'inherit' ELSE NULL END; ) ; CREATE FUNCTION update_sqltable_data( text, text, bigint ) RETURNS VOID AS $$ DECLARE tablelist ALIAS FOR $1; tabletype ALIAS FOR $2; node_id ALIAS FOR $3; tablename varchar; BEGIN DELETE FROM node_sqltable WHERE nodetype_id = node_id AND sqltable in ( SELECT sqltable_pk FROM sqltable, sqltable_type WHERE sqltable.type = sqltable_type_pk AND sqltable_type.sqltable_type = tabletype); PERFORM insert_sqltable_data( tablelist, tabletype, node_id ); RETURN; END; $$ LANGUAGE plpgsql ; CREATE FUNCTION update_node_authorisation (bigint, integer, varchar ) RETURNS VOID AS $$ -- nodetype_id, authorisation, authorisation_type DELETE FROM node_authorisation WHERE node_authorisation.node_id = $1 AND node_authorisation.permission_type = ( SELECT permission_type.permission_type_pk FROM permission_type WHERE permission_type.permission = $3) AND $2 IS NULL; UPDATE node_authorisation SET permission_behaviour = ( SELECT permission_behaviour_pk FROM permission_behaviour WHERE permission_behaviour.behaviour = CASE $2 WHEN '1' THEN 'enable' WHEN '0' THEN 'disable' WHEN '-1' THEN 'inherit' ELSE NULL END ) WHERE node_authorisation.node_id = $1 AND node_authorisation.permission_type = ( SELECT permission_type_pk FROM permission_type where permission_type.permission = $3 ); INSERT INTO node_authorisation ( node_id, permission_type, permission_behaviour ) SELECT $1, permission_type.permission_type_pk, permission_behaviour.permission_behaviour_pk FROM permission_type, permission_behaviour WHERE permission_type.permission = $3 AND NOT EXISTS ( SELECT * FROM node_authorisation, permission_type WHERE node_authorisation.node_id = $1 AND node_authorisation.permission_type = permission_type.permission_type_pk AND permission_type.permission = $3) AND permission_behaviour.behaviour = ( SELECT CASE $2 WHEN '1' THEN 'enable' WHEN '0' THEN 'disable' WHEN '-1' THEN 'inherit' ELSE NULL END ); $$ LANGUAGE SQL; ; CREATE RULE _update_nodetype AS ON UPDATE to nodetype DO INSTEAD ( SELECT update_node_relation( NEW.nodetype_id, NEW.restrict_nodetype, 'restrict_nodetype') WHERE NEW.restrict_nodetype <> 0; SELECT update_node_relation( NEW.nodetype_id, NEW.extends_nodetype, 'extends_nodetype') WHERE NEW.extends_nodetype <> 0; SELECT update_node_authorisation( NEW.nodetype_id, NEW.restrictdupes, 'restrictdupes'); SELECT update_sqltable_data( NEW.sqltable, 'attributetable', NEW.nodetype_id ); SELECT update_sqltable_data( NEW.grouptable, 'grouptable', NEW.nodetype_id ); SELECT update_permissions( NEW.nodetype_id, 'defaultauthor', NEW.defaultauthoraccess ); SELECT update_permissions( NEW.nodetype_id, 'defaultgroup', NEW.defaultgroupaccess ); SELECT update_permissions( NEW.nodetype_id, 'defaultother', NEW.defaultotheraccess ); SELECT update_permissions( NEW.nodetype_id, 'defaultguest', NEW.defaultguestaccess ); SELECT update_node_relation( NEW.nodetype_id, NEW.defaultgroup_usergroup, 'defaultgroup_usergroup' ) WHERE NEW.defaultgroup_usergroup <> 0; SELECT update_dynamicpermission ( NEW.nodetype_id, 'defaultauthor', NEW.defaultauthor_permission ); SELECT update_dynamicpermission ( NEW.nodetype_id, 'defaultgroup', NEW.defaultgroup_permission ); SELECT update_dynamicpermission ( NEW.nodetype_id, 'defaultother', NEW.defaultother_permission ); SELECT update_dynamicpermission ( NEW.nodetype_id, 'defaultguest', NEW.defaultguest_permission ); DELETE FROM nodebase_node_revisions WHERE nodebase_node_revisions.node_id = NEW.nodetype_id AND NEW.maxrevisions IS NULL; UPDATE nodebase_node_revisions SET maxrevisions=NEW.maxrevisions WHERE NEW.maxrevisions IS NOT NULL AND nodebase_node_revisions.node_id = NEW.nodetype_id AND EXISTS (SELECT * FROM nodebase_node_revisions where nodebase_node_revisions.node_id = NEW.nodetype_id ); INSERT INTO nodebase_node_revisions (node_id, maxrevisions ) SELECT NEW.nodetype_id, NEW.maxrevisions WHERE NEW.maxrevisions IS NOT NULL AND NOT EXISTS (SELECT * FROM nodebase_node_revisions WHERE nodebase_node_revisions.node_id = NEW.nodetype_id); SELECT update_node_authorisation ( NEW.nodetype_id, NEW.canworkspace, 'canworkspace' ); ) ; CREATE TABLE version ( version_id INTEGER PRIMARY KEY DEFAULT '0' NOT NULL, version INTEGER DEFAULT '1' NOT NULL ); INSERT INTO sqltable_type ( sqltable_type, description) VALUES ('attributetable', 'A table of this type contains node attribute data.') ; INSERT INTO sqltable_type ( sqltable_type, description) VALUES ('grouptable', 'A table of this type contains a list of nodes contained in a type.') ; INSERT INTO node_relation_type ( name, description ) VALUES ('author_user', 'the user node identified as author of a node') ; INSERT INTO node_relation_type ( name, description ) VALUES ('group_usergroup', 'the usergroup node associated with a node') ; INSERT INTO node_relation_type ( name, description ) VALUES ('defaultgroup_usergroup', 'the default usergroup node associated with a node') ; INSERT INTO node_relation_type ( name, description ) VALUES ('extends_nodetype', 'the nodetype that this node extends') ; INSERT INTO node_relation_type ( name, description ) VALUES ('type_nodetype', 'the nodetype node of a node') ; INSERT INTO node_relation_type ( name, description ) VALUES ('loc_location', 'the location node of a node') ; INSERT INTO node_relation_type ( name, description ) VALUES ('restrict_nodetype', 'for group nodes: restrict the nodes contained in this group to this type.') ; INSERT INTO node_relation_type ( name, description ) VALUES ('dynamic permission', 'where access to a node is determined by a perimssion node.') ; INSERT INTO node_relation_type ( name, description ) VALUES ('permission', 'a dynamic permission node for the node') ; INSERT INTO user_type (usertype, description) VALUES ('author', 'an author of a node'); INSERT INTO user_type (usertype, description) VALUES ('group', 'whether an author is a member of a group'); INSERT INTO user_type (usertype, description) VALUES ('other', 'a user is logged in but is neither in the relevant group not an author'); INSERT INTO user_type (usertype, description) VALUES ('guest', 'usually used to refer to an anonymous user or one that is not in any other category'); INSERT INTO user_type (usertype, description) VALUES ('defaultauthor', 'what an author type defaults to.'); INSERT INTO user_type (usertype, description) VALUES ('defaultgroup', 'what members of a group default to.'); INSERT INTO user_type (usertype, description) VALUES ('defaultother', 'what other users default to.'); INSERT INTO user_type (usertype, description) VALUES ('defaultguest', 'what guests default to.'); INSERT INTO permission_type (permission, description) VALUES ('read', 'the permission to read an object'); INSERT INTO permission_type (permission, description) VALUES ('write', 'the permission to write to an object'); INSERT INTO permission_type (permission, description) VALUES ('execute', 'the permission to "execute" an object, that is, run any code in it'); INSERT INTO permission_type (permission, description) VALUES ('delete', 'the permission to delete an object'); INSERT INTO permission_type (permission, description) VALUES ('create', 'the permission to create an object'); INSERT INTO permission_type (permission, description) VALUES ('canworkspace', 'whether the node can be workspaced'); INSERT INTO permission_type (permission, description) VALUES ('restrictdupes', 'whether the nodebase allows creation of nodes with a similar name'); INSERT INTO permission_behaviour (behaviour, description) VALUES ('enable', 'the permission for this object is enabled'); INSERT INTO permission_behaviour (behaviour, description) VALUES ('disable', 'the permission for this object is disabled'); INSERT INTO permission_behaviour (behaviour, description) VALUES ('inherit', 'the permission for this object is inherited according to some algorithm'); INSERT INTO node (node_id, type_nodetype, title, createtime, authoraccess, groupaccess, otheraccess, guestaccess ) VALUES (1,1,'nodetype',now(), 'iiii','rwxdc','-----','-----' ); INSERT INTO node (node_id, type_nodetype, title, createtime, authoraccess, groupaccess, otheraccess, guestaccess ) VALUES (2,1,'node',now(),'rwxd','-----','-----','-----'); INSERT INTO node (node_id, type_nodetype, title, createtime, authoraccess, groupaccess, otheraccess, guestaccess ) VALUES (3,1,'setting', now(),'rwxd','-----','-----','-----'); INSERT INTO nodetype (nodetype_id, restrict_nodetype, extends_nodetype, restrictdupes, sqltable, grouptable, defaultauthoraccess, defaultgroupaccess, defaultotheraccess, defaultguestaccess, defaultgroup_usergroup, defaultauthor_permission, defaultgroup_permission, defaultother_permission, defaultguest_permission, maxrevisions, canworkspace ) VALUES (1,NULL,2,1,'nodetype','','rwxd','rwxdc','-----','-----',NULL,NULL,NULL,NULL,NULL,-1,0); INSERT INTO nodetype (nodetype_id, restrict_nodetype, extends_nodetype, restrictdupes, sqltable, grouptable, defaultauthoraccess, defaultgroupaccess, defaultotheraccess, defaultguestaccess, defaultgroup_usergroup, defaultauthor_permission, defaultgroup_permission, defaultother_permission, defaultguest_permission, maxrevisions, canworkspace ) VALUES (2,NULL,NULL,1,'','','rwxd','r----','-----','-----',NULL,NULL,NULL,NULL,NULL,1000,1); INSERT INTO nodetype (nodetype_id, restrict_nodetype, extends_nodetype, restrictdupes, sqltable, grouptable, defaultauthoraccess, defaultgroupaccess, defaultotheraccess, defaultguestaccess, defaultgroup_usergroup, defaultauthor_permission, defaultgroup_permission, defaultother_permission, defaultguest_permission, maxrevisions, canworkspace ) VALUES (3,NULL,2,1,'setting','','rwxd','-----','-----','-----',NULL,NULL,NULL,NULL,NULL,-1,-1) |
From: <pau...@us...>
<pau...@us...> - 2009-01-23 12:38:43
|
Hi Nate, Another question. "Everything Development, Inc" sounds like a registered corporation. Is it still a registered corporation, or was it dissolved? Cheers, Paul Nathan Oostendorp wrote: > Hey Paul, > > To address point #2, I agree that this list is pretty dead. I'd would > encourage you to put these someplace public, like on a blog or > everydevel (of course still sitting under my desk without network until > the bastards at comcast fix our internet connection). This way people > can just reply as they want to, without being list subscribers. > > I also think if you're really interested in keeping it alive long term > you should consider "forking" or otherwise re-branding the project and > then either doing regular releases, or making it a micro-packaged > SVN-distributed project (ala ruby gems). "Everything Engine" has always > been a kind of an ad-hoc name, and i think most of the people that have > heard of it just associate it with Everything2, which I don't think is > what you're ultimately aiming for. I think you need to reframe the > fundamental pitch to say "HEY, WE'RE LIKE DRUPAL BUT PERL BUT ALSO > BETTER BECAUSE WE DO X AND Y AND Z", since CMSs are a dime a dozen now. > > If there's anything I can do, please let me know. > > --n > > > > > > On Jan 9, 2009, at 4:31 AM, pau...@us... wrote: > >> Hello list, >> >> Two points here: >> >> POINT ONE >> ========= >> >> The latest thing I've been working on in everydevel is changing the >> database structure for more normalisation. The good news is that this >> works. The bad news is that it is taking me longer than I thought >> partly because I've had to do a lot of thinking and partly because there >> is no one to bounce ideas off. >> >> These changes in the db layer have to have knock on effects. I'll give >> you an example: permissions. >> >> As you know permissions in everydevel have five types r, w, x, d, c and >> there are four user types for each permission: owner, group, other, >> guest. >> >> After my db redesign it is obvious that this is arbitrary and there >> could be more permission types and user types. >> >> It is also has become obvious that nodes can't continue to 'know' about >> their own permissions. Because to do so they'd also have to continue to >> 'know' about any 'usertype' nodes in the nodebase to which they belong. >> This means that each and every node would have to have some sort of >> aggregate behaviour as well as their standard behaviour. >> >> This of course is waaaay too complicated and indicates a design problem. >> >> The solution is to change Security.pm into an object class that >> negotiates permissions, or perhaps to make Security.pm a nodetype that >> has the job of negotiating access between the UI and the NodeBase. >> >> Anyway, the point is these knock on effects get a bit involved. >> >> >> POINT TWO >> ========= >> >> I'm not sure there's any point posting to this list any more, because >> I get barely any response and never any assistance .... then some >> smartarse wonders why things are going so slowly.... >> >> Nonetheless, I'd really like to create enthusiasm for everydevel. It is >> afterall one of the few CMS which are perl based in a world where PHP >> rules in the space. The question is how to create this enthusiasm and >> where. >> >> Experience suggests it isn't here. But where? >> >> Paul >> >> ------------------------------------------------------------------------------ >> >> Check out the new SourceForge.net Marketplace. >> It is the best place to buy or sell services for >> just about anything Open Source. >> http://p.sf.net/sfu/Xq1LFB >> _______________________________________________ >> Everydevel-opers mailing list >> Eve...@li... >> https://lists.sourceforge.net/lists/listinfo/everydevel-opers > > > |
From: <pau...@us...>
<pau...@us...> - 2009-01-22 23:14:35
|
Hi Nate, Thanks for this.I've been thinking of forking for a while, not so much because Everydevel is linked to Everything2, but because it would stop me feeling constrained by the code base. It would also make version numbering easier. One of the reasons I haven't suggested a release is because the current version is pre-1.0, what should the next release be 2.0? But a name change and starting at version 0.01 would be easier. Also, it means I could host it on a git server. As for being better than Drupal, I actually think Everything is already better in the fact it is far more flexible. Drupal is easier for novices to get up and running with though. Cheers Paul Nathan Oostendorp wrote: > Hey Paul, > > To address point #2, I agree that this list is pretty dead. I'd would > encourage you to put these someplace public, like on a blog or > everydevel (of course still sitting under my desk without network until > the bastards at comcast fix our internet connection). This way people > can just reply as they want to, without being list subscribers. > > I also think if you're really interested in keeping it alive long term > you should consider "forking" or otherwise re-branding the project and > then either doing regular releases, or making it a micro-packaged > SVN-distributed project (ala ruby gems). "Everything Engine" has always > been a kind of an ad-hoc name, and i think most of the people that have > heard of it just associate it with Everything2, which I don't think is > what you're ultimately aiming for. I think you need to reframe the > fundamental pitch to say "HEY, WE'RE LIKE DRUPAL BUT PERL BUT ALSO > BETTER BECAUSE WE DO X AND Y AND Z", since CMSs are a dime a dozen now. > > If there's anything I can do, please let me know. > > --n > > > > > > On Jan 9, 2009, at 4:31 AM, pau...@us... wrote: > >> Hello list, >> >> Two points here: >> >> POINT ONE >> ========= >> >> The latest thing I've been working on in everydevel is changing the >> database structure for more normalisation. The good news is that this >> works. The bad news is that it is taking me longer than I thought >> partly because I've had to do a lot of thinking and partly because there >> is no one to bounce ideas off. >> >> These changes in the db layer have to have knock on effects. I'll give >> you an example: permissions. >> >> As you know permissions in everydevel have five types r, w, x, d, c and >> there are four user types for each permission: owner, group, other, >> guest. >> >> After my db redesign it is obvious that this is arbitrary and there >> could be more permission types and user types. >> >> It is also has become obvious that nodes can't continue to 'know' about >> their own permissions. Because to do so they'd also have to continue to >> 'know' about any 'usertype' nodes in the nodebase to which they belong. >> This means that each and every node would have to have some sort of >> aggregate behaviour as well as their standard behaviour. >> >> This of course is waaaay too complicated and indicates a design problem. >> >> The solution is to change Security.pm into an object class that >> negotiates permissions, or perhaps to make Security.pm a nodetype that >> has the job of negotiating access between the UI and the NodeBase. >> >> Anyway, the point is these knock on effects get a bit involved. >> >> >> POINT TWO >> ========= >> >> I'm not sure there's any point posting to this list any more, because >> I get barely any response and never any assistance .... then some >> smartarse wonders why things are going so slowly.... >> >> Nonetheless, I'd really like to create enthusiasm for everydevel. It is >> afterall one of the few CMS which are perl based in a world where PHP >> rules in the space. The question is how to create this enthusiasm and >> where. >> >> Experience suggests it isn't here. But where? >> >> Paul >> >> ------------------------------------------------------------------------------ >> >> Check out the new SourceForge.net Marketplace. >> It is the best place to buy or sell services for >> just about anything Open Source. >> http://p.sf.net/sfu/Xq1LFB >> _______________________________________________ >> Everydevel-opers mailing list >> Eve...@li... >> https://lists.sourceforge.net/lists/listinfo/everydevel-opers > > > |
From: <pau...@us...>
<pau...@us...> - 2009-01-09 10:10:11
|
Hello list, Two points here: POINT ONE ========= The latest thing I've been working on in everydevel is changing the database structure for more normalisation. The good news is that this works. The bad news is that it is taking me longer than I thought partly because I've had to do a lot of thinking and partly because there is no one to bounce ideas off. These changes in the db layer have to have knock on effects. I'll give you an example: permissions. As you know permissions in everydevel have five types r, w, x, d, c and there are four user types for each permission: owner, group, other, guest. After my db redesign it is obvious that this is arbitrary and there could be more permission types and user types. It is also has become obvious that nodes can't continue to 'know' about their own permissions. Because to do so they'd also have to continue to 'know' about any 'usertype' nodes in the nodebase to which they belong. This means that each and every node would have to have some sort of aggregate behaviour as well as their standard behaviour. This of course is waaaay too complicated and indicates a design problem. The solution is to change Security.pm into an object class that negotiates permissions, or perhaps to make Security.pm a nodetype that has the job of negotiating access between the UI and the NodeBase. Anyway, the point is these knock on effects get a bit involved. POINT TWO ========= I'm not sure there's any point posting to this list any more, because I get barely any response and never any assistance .... then some smartarse wonders why things are going so slowly.... Nonetheless, I'd really like to create enthusiasm for everydevel. It is afterall one of the few CMS which are perl based in a world where PHP rules in the space. The question is how to create this enthusiasm and where. Experience suggests it isn't here. But where? Paul |
From: <pau...@us...> - 2008-10-20 14:31:17
|
Revision: 1017 http://everydevel.svn.sourceforge.net/everydevel/?rev=1017&view=rev Author: paul_the_nomad Date: 2008-10-20 14:31:07 +0000 (Mon, 20 Oct 2008) Log Message: ----------- Squashed commit of the following: commit 71120bd98a9aaf239024d7c218114ead3d0899e8 Author: Paul <paul@aglaea.oceanos> Date: Mon Oct 20 15:14:26 2008 +0100 Patch reversing the effects of a FUBAR created by the way that git-svn squashes git commits before applying them to a subversion repository. commit efac9219c8c711ff04c4a018cef2bca1412c55fb Merge: 8e23dc3... 455dce8... Author: Paul <paul@aglaea.oceanos> Date: Thu Oct 16 16:37:45 2008 +0100 Merge /home/paul/git/edev commit 455dce8923aa2d3db9fab8cdcde12c3c1e79c7aa Merge: 2001008... 93e93ac... Author: Paul <paul@aglaea.oceanos> Date: Tue Oct 14 21:12:13 2008 +0100 Merge /home/paul/git-svn/edev commit 93e93ac1bc592ae67b94f2c692f2baf3972cfcfc Author: Paul <paul@paul1.oceanos> Date: Tue Jul 15 12:46:48 2008 +0100 Capitalise nodelet titles. And codelisting in monospace rather than fixed. Modified Paths: -------------- trunk/ebase/TODO trunk/ebase/lib/Everything/DB/Pg.pm trunk/ebase/lib/Everything/DB/Test/Pg.pm trunk/ebase/lib/Everything/DB/mysql.pm trunk/ebase/t/DB/Live/Pg.t trunk/ebase/t/DB/Live/mysql.t Modified: trunk/ebase/TODO =================================================================== --- trunk/ebase/TODO 2008-10-15 21:28:26 UTC (rev 1016) +++ trunk/ebase/TODO 2008-10-20 14:31:07 UTC (rev 1017) @@ -7,15 +7,7 @@ * Amend FromObject.pm so that form objects return labels with a 'for' attribute and id in the input tag. -<<<<<<< HEAD:ebase/TODO -======= -* Require Everything::HTML::Response classes to create certain HTTP headers - -* Everything::HTML::Response classes to return error values on error - - e.g. Forbidden ->>>>>>> Changes to the response class interface:ebase/TODO - * Change default DB (for all DBs) setup so default encoding is utf8 * Documentation - Ecore should be self documenting Modified: trunk/ebase/lib/Everything/DB/Pg.pm =================================================================== --- trunk/ebase/lib/Everything/DB/Pg.pm 2008-10-15 21:28:26 UTC (rev 1016) +++ trunk/ebase/lib/Everything/DB/Pg.pm 2008-10-20 14:31:07 UTC (rev 1017) @@ -80,6 +80,11 @@ while ( my $field = $cursor->fetchrow_hashref ) { + + # DBD::Pg seems to automatically quote some (but not + # all) column names. This is a workaround. + $$field{COLUMN_NAME} =~ s/^"?(.*?)"?$/$1/; + # for backwards compatibility $$field{Field} = $$field{COLUMN_NAME}; @@ -683,14 +688,13 @@ $host ||= 'localhost'; my $dbh; - if ( $dbname ) { - undef $this->{dbh}; - undef $this->{nb}; - $dbh = DBI->connect( "DBI:Pg:dbname=postgres;host=$host;port=$port", + $dbh = DBI->connect( "DBI:Pg:dbname=postgres;host=$host;port=$port", $user, $password ) or die "Unable to get database connection!"; - } else { - $dbh = $this->getDatabaseHandle; + + if ( ref $this ) { + undef $this->{nb}; + undef $this->{dbh}; } $dbh->do( "drop database $dbname" ); Modified: trunk/ebase/lib/Everything/DB/Test/Pg.pm =================================================================== --- trunk/ebase/lib/Everything/DB/Test/Pg.pm 2008-10-15 21:28:26 UTC (rev 1016) +++ trunk/ebase/lib/Everything/DB/Test/Pg.pm 2008-10-20 14:31:07 UTC (rev 1017) @@ -81,7 +81,7 @@ can_ok( $self->{class}, 'getFieldsHash' ) || return; $self->{instance}->{nb}->clear; $self->{instance}->{dbh}->clear; - my $fields = [ { Field => 'foo', foo => 1 }, { Field => 'bar', bar => 2 } ]; + my $fields = [ { COLUMN_NAME => 'foo', foo => 1 }, { COLUMN_NAME => 'bar', bar => 2 } ]; $self->{instance}->{dbh}->mock( 'column_info', sub { shift; } ); $self->{instance}->{dbh}->set_series( 'fetchrow_hashref', @$fields ); $self->{instance}->{dbh}->set_false( 'err' ); Modified: trunk/ebase/lib/Everything/DB/mysql.pm =================================================================== --- trunk/ebase/lib/Everything/DB/mysql.pm 2008-10-15 21:28:26 UTC (rev 1016) +++ trunk/ebase/lib/Everything/DB/mysql.pm 2008-10-20 14:31:07 UTC (rev 1017) @@ -508,8 +508,11 @@ sub drop_database { my ( $this, $dbname, $user, $password, $host, $port ) = @_; + $host ||= ''; + $port ||= ''; + my $dbh; - if ( $dbname ) { + if ( ! ref $this || ! $this->{dbh} ) { $dbh = DBI->connect( "DBI:mysql:$dbname:$host", $user, $password ) or die "Unable to get database connection!"; } else { @@ -517,7 +520,12 @@ } $dbh->do( "drop database $dbname" ); - die $DBI::errstr if $DBI::errstr; + + if ( $DBI::errstr ) { + die $DBI::errstr; + return 0; + } + return 1; } Modified: trunk/ebase/t/DB/Live/Pg.t =================================================================== --- trunk/ebase/t/DB/Live/Pg.t 2008-10-15 21:28:26 UTC (rev 1016) +++ trunk/ebase/t/DB/Live/Pg.t 2008-10-20 14:31:07 UTC (rev 1017) @@ -1,27 +1,36 @@ #!/usr/bin/perl -use Everything::DB::Test::Live::Pg; +use lib 't/lib'; +use DBTestUtil qw/config_file skip_cond/; +use Everything::DB::Test::Live; use strict; use warnings; + # touch 't/lib/db/run-tests' to run. my $RUN_TESTS = -e 't/lib/db/run-tests'; my $msg; -my $config = Everything::Config->new( file => 't/lib/db/Pg.conf' ); +my $config_file = config_file(); +my @config_args; + +push @config_args, file => $config_file if -e $config_file; + +my $config = Everything::Config->new( @config_args ); + if ( ! $RUN_TESTS ) { - Everything::DB::Test::Live::Pg->SKIP_CLASS('Time consuming live database tests skipped by default.') unless $RUN_TESTS; + Everything::DB::Test::Live->SKIP_CLASS('Time consuming live database tests skipped by default.') unless $RUN_TESTS; } elsif ( ! $config->database_superuser ) { - Everything::DB::Test::Live::Pg->SKIP_CLASS('Skipping tests database super user must be set.') + Everything::DB::Test::Live->SKIP_CLASS('Skipping tests database super user must be set.') } -my $tests = Everything::DB::Test::Live::Pg->new( config => $config, SKIP => $msg ) ; +my $tests = Everything::DB::Test::Live->new( config => $config, SKIP => $msg ) ; $tests->runtests; Modified: trunk/ebase/t/DB/Live/mysql.t =================================================================== --- trunk/ebase/t/DB/Live/mysql.t 2008-10-15 21:28:26 UTC (rev 1016) +++ trunk/ebase/t/DB/Live/mysql.t 2008-10-20 14:31:07 UTC (rev 1017) @@ -1,5 +1,7 @@ #!/usr/bin/perl +use lib 't/lib'; +use DBTestUtil qw/config_file skip_cond/; use Everything::DB::Test::Live; use strict; use warnings; @@ -10,8 +12,14 @@ my $msg; -my $config = Everything::Config->new( file => 't/lib/db/mysql.conf' ); +my $config_file = config_file(); +my @config_args; + +push @config_args, file => $config_file if -e $config_file; + +my $config = Everything::Config->new( @config_args ); + if ( ! $RUN_TESTS ) { Everything::DB::Test::Live->SKIP_CLASS('Time consuming live database tests skipped by default.') unless $RUN_TESTS; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pau...@us...> - 2008-10-15 21:28:35
|
Revision: 1016 http://everydevel.svn.sourceforge.net/everydevel/?rev=1016&view=rev Author: paul_the_nomad Date: 2008-10-15 21:28:26 +0000 (Wed, 15 Oct 2008) Log Message: ----------- Merge branch 'master' of /home/paul/git/edev into HEAD Conflicts: ebase/lib/Everything/DB/Pg.pm ebase/lib/Everything/DB/Test/Pg.pm ebase/lib/Everything/DB/mysql.pm ebase/t/DB/Live/Pg.t ebase/t/DB/Live/mysql.t Modified Paths: -------------- trunk/ebase/Build.PL trunk/ebase/lib/Everything/Auth/Test/EveryAuth.pm trunk/ebase/lib/Everything/Build.pm trunk/ebase/lib/Everything/DB/Pg.pm trunk/ebase/lib/Everything/DB/Test/Pg.pm trunk/ebase/lib/Everything/DB/mysql.pm trunk/ebase/lib/Everything/HTTP/Apache.pm trunk/ebase/lib/Everything/HTTP/Test/Apache.pm trunk/ebase/lib/Everything/HTTP/Test/CGI.pm trunk/ebase/lib/Everything/Storage/Nodeball.pm trunk/ebase/lib/Everything/Test/DB.pm trunk/ebase/lib/Everything/Test/Ecore/Compile.pm trunk/ebase/lib/Everything/Test/Ecore/Install.pm trunk/ebase/lib/Everything/Test/HTML.pm trunk/ebase/lib/Everything/Test/NodeBase.pm Added Paths: ----------- trunk/ebase/t/ecore/Pg/ trunk/ebase/t/ecore/Pg/010-install.t trunk/ebase/t/ecore/Pg/020-compile.t trunk/ebase/t/ecore/Pg/090-drop-database.t trunk/ebase/t/ecore/mysql/ trunk/ebase/t/ecore/mysql/010-install.t trunk/ebase/t/ecore/mysql/020-compile.t trunk/ebase/t/ecore/mysql/090-drop-database.t trunk/ebase/t/ecore/sqlite/ trunk/ebase/t/ecore/sqlite/010-install.t trunk/ebase/t/ecore/sqlite/020-compile.t trunk/ebase/t/ecore/sqlite/090-drop-database.t trunk/ebase/t/lib/DBTestUtil.pm trunk/ebase/t/lib/db/Pg.conf.template trunk/ebase/t/lib/db/mysql.conf.template Modified: trunk/ebase/Build.PL =================================================================== --- trunk/ebase/Build.PL 2008-10-15 20:15:59 UTC (rev 1015) +++ trunk/ebase/Build.PL 2008-10-15 21:28:26 UTC (rev 1016) @@ -36,7 +36,7 @@ 'Mail::Sender' => 0, 'Scalar::Util' => 1.01, 'SUPER' => 1.16, - 'Object::InsideOut' => 3.21, + 'Object::InsideOut' => 3.46, 'Archive::Tar' => 0, 'Class::Factory' => 0, 'SQL::Statement' => 1.15, @@ -54,7 +54,7 @@ 'File::Temp' => 0.18, }, scripts => [ File::Spec->catfile( 'bin', 'nbmasta' ) ], - test_files => join( ' ', @test_files ), + test_files => join( ' ', sort @test_files ), ); my $httpconf = ''; Modified: trunk/ebase/lib/Everything/Auth/Test/EveryAuth.pm =================================================================== --- trunk/ebase/lib/Everything/Auth/Test/EveryAuth.pm 2008-10-15 20:15:59 UTC (rev 1015) +++ trunk/ebase/lib/Everything/Auth/Test/EveryAuth.pm 2008-10-15 21:28:26 UTC (rev 1016) @@ -165,7 +165,7 @@ { title => $name, passwd => $pw, lasttime => 'timestamp' }; my $crypted = crypt( $pw, $name ); $mock->set_series( 'getNode', undef, $expected_rv ); - $mock->set_true('getType'); + $mock->set_true('getType', 'now'); $mock->set_always( 'sqlSelect', 'timestamp' ); my $confirmUser = \&{ $class . '::confirmUser' }; Modified: trunk/ebase/lib/Everything/Build.pm =================================================================== --- trunk/ebase/lib/Everything/Build.pm 2008-10-15 20:15:59 UTC (rev 1015) +++ trunk/ebase/lib/Everything/Build.pm 2008-10-15 21:28:26 UTC (rev 1016) @@ -9,15 +9,6 @@ use vars '@ISA'; @ISA = 'Module::Build'; -sub ACTION_test -{ - my $self = shift; - my @files; - - find( sub { /\.t\z/ and push @files, $File::Find::name }, 't' ); - $self->SUPER::ACTION_test( 'test_files=' . join( ' ', @files ) ); -} - sub ACTION_install { my $self = shift; Modified: trunk/ebase/lib/Everything/DB/Pg.pm =================================================================== --- trunk/ebase/lib/Everything/DB/Pg.pm 2008-10-15 20:15:59 UTC (rev 1015) +++ trunk/ebase/lib/Everything/DB/Pg.pm 2008-10-15 21:28:26 UTC (rev 1016) @@ -137,9 +137,24 @@ } sub databaseExists { - my ( $self, $database ) = @_; - my $c = $self->{dbh}->prepare("select count(1) from pg_catalog.pg_database where datname = ?"); + my ( $self, $database, $user, $password, $host, $port ) = @_; + + $host ||= 'localhost'; + $port ||= 5432; + + my $dbh; + + if ( ! ref $self || ! $self->{dbh} ) { + $dbh = DBI->connect( "DBI:Pg:dbname=postgres;host=$host;port=$port", $user, $password ); + } else { + + $dbh = $self->getDatabaseHandle + + } + + my $c = $dbh->prepare("select count(1) from pg_catalog.pg_database where datname = ?"); + $c->execute( $database ); my ( $rv ) = $c->fetchrow; return $rv; @@ -269,6 +284,8 @@ # Text blobs cannot have default strings. They need to be empty. $default = ""; + } elsif ( not defined $default ) { + $default = ''; } $sql = "alter table \"$table\" add $fieldname $type"; Modified: trunk/ebase/lib/Everything/DB/Test/Pg.pm =================================================================== --- trunk/ebase/lib/Everything/DB/Test/Pg.pm 2008-10-15 20:15:59 UTC (rev 1015) +++ trunk/ebase/lib/Everything/DB/Test/Pg.pm 2008-10-15 21:28:26 UTC (rev 1016) @@ -404,9 +404,9 @@ #### if the new field is a primary key but there is no current primary key $fields = [ - { Field => 'foo', Key => '' }, - { Field => 'bar', Key => '' }, - { Field => 'baz', Key => '' } + { COLUMN_NAME => 'foo', Key => '' }, + { COLUMN_NAME => 'bar', Key => '' }, + { COLUMN_NAME => 'baz', Key => '' } ]; $self->{instance}->{dbh}->set_series( 'fetchrow_hashref', @$fields )->clear; Modified: trunk/ebase/lib/Everything/DB/mysql.pm =================================================================== --- trunk/ebase/lib/Everything/DB/mysql.pm 2008-10-15 20:15:59 UTC (rev 1015) +++ trunk/ebase/lib/Everything/DB/mysql.pm 2008-10-15 21:28:26 UTC (rev 1016) @@ -383,8 +383,19 @@ sub databaseExists { - my ( $this, $database ) = @_; - my $sth = $this->{dbh}->prepare('show databases'); + my ( $this, $database, $user, $password, $host, $port ) = @_; + + my $dbh; + + if ( ! ref $this || ! $this->{dbh} ) { + $dbh = DBI->connect( "DBI:mysql:database=mysql;host=$host;port=$port", $user, $password ); + } else { + + $dbh = $this->getDatabaseHandle + + } + + my $sth = $dbh->prepare('show databases'); $sth->execute(); while ( my ($dbname) = $sth->fetchrow() ) Modified: trunk/ebase/lib/Everything/HTTP/Apache.pm =================================================================== --- trunk/ebase/lib/Everything/HTTP/Apache.pm 2008-10-15 20:15:59 UTC (rev 1015) +++ trunk/ebase/lib/Everything/HTTP/Apache.pm 2008-10-15 21:28:26 UTC (rev 1016) @@ -73,12 +73,6 @@ ### XXX- response factory should set up the environment that htmlpage needs my $response = Everything::HTTP::ResponseFactory->new( $e->get_response_type || 'htmlpage', { config => $config, request => $e } ); - - ### new actually creates the response - so get rid of 'create http body' - ### check response code - ### check headers - ### check content - ### return status_code my $html = $response->content(); Modified: trunk/ebase/lib/Everything/HTTP/Test/Apache.pm =================================================================== --- trunk/ebase/lib/Everything/HTTP/Test/Apache.pm 2008-10-15 20:15:59 UTC (rev 1015) +++ trunk/ebase/lib/Everything/HTTP/Test/Apache.pm 2008-10-15 21:28:26 UTC (rev 1016) @@ -24,6 +24,7 @@ $mock->set_true(qw/content/) ->set_always( content_type => 'a mime type' ) ->set_always( 'content', 'the html body' ); + $mock->set_list('-headers', () ); $mock->set_always( status_code => 0 ); $self->{class} = $self->module_class; Modified: trunk/ebase/lib/Everything/HTTP/Test/CGI.pm =================================================================== --- trunk/ebase/lib/Everything/HTTP/Test/CGI.pm 2008-10-15 20:15:59 UTC (rev 1015) +++ trunk/ebase/lib/Everything/HTTP/Test/CGI.pm 2008-10-15 21:28:26 UTC (rev 1016) @@ -26,7 +26,7 @@ 'setup_standard_system_vars', '-get_initializer', 'set_cgi_standard', 'set_node_from_cgi', 'setup_everything_html', 'authorise_user', - 'execute_opcodes', 'print' + 'execute_opcodes', 'print', '-content_type' ); $mock->set_series( 'isOfType', 0, 0, 1, 1, 0, 1, 1, 0 ); Modified: trunk/ebase/lib/Everything/Storage/Nodeball.pm =================================================================== --- trunk/ebase/lib/Everything/Storage/Nodeball.pm 2008-10-15 20:15:59 UTC (rev 1015) +++ trunk/ebase/lib/Everything/Storage/Nodeball.pm 2008-10-15 21:28:26 UTC (rev 1016) @@ -1072,7 +1072,7 @@ #don't let this bite you in the ass - return unless ( -e $dir and -d $dir and !( -l $dir ) ); + return unless ( defined $dir and -e $dir and -d $dir and !( -l $dir ) ); use File::Path; rmtree($dir); } Modified: trunk/ebase/lib/Everything/Test/DB.pm =================================================================== --- trunk/ebase/lib/Everything/Test/DB.pm 2008-10-15 20:15:59 UTC (rev 1015) +++ trunk/ebase/lib/Everything/Test/DB.pm 2008-10-15 21:28:26 UTC (rev 1016) @@ -96,6 +96,7 @@ $self->{instance}->{dbh}->set_true('finish', 'do', '-begin_work', '-rollback', '-commit'); + $self->{instance}->{dbh}->set_false(qw/-err/); } Modified: trunk/ebase/lib/Everything/Test/Ecore/Compile.pm =================================================================== --- trunk/ebase/lib/Everything/Test/Ecore/Compile.pm 2008-10-15 20:15:59 UTC (rev 1015) +++ trunk/ebase/lib/Everything/Test/Ecore/Compile.pm 2008-10-15 21:28:26 UTC (rev 1016) @@ -3,6 +3,7 @@ use base 'Test::Class'; use Everything::HTML (); +use Everything (); use HTML::Lint; use Test::More; use Test::MockObject; @@ -11,11 +12,45 @@ use strict; use warnings; +## error handling - until error handling is made more flexible + +my $err; +no warnings 'redefine'; +*Everything::getFrontsideErrors =sub { + + my @temp = @Everything::fsErrors; + $err = \@temp; + return \@Everything::fsErrors; +}; +use warnings 'redefine'; + +sub report_error { + + diag join( "\n", map { join "\n", $_->{context}->get_title, $_->{context}->get_node_id, $_->{error} } @$err); + +} + + +sub test_node_error { + my $node = shift; + + my $error = join "\n", map { $_->{error} } @$err; + is( $error, '', +"...execute node $$node{title}, type $$node{type}{title}, id, $$node{node_id}" + ) || report_error(); + +} + +sub SKIP_CLASS { + my $self = shift; + my $class = ref $self ? ref $self : $self; + $class->SUPER( @_ ); +} + sub startup : Test( startup ) { my $self = shift; - my $nb = $self->{nodebase} - || croak "Must have a nodebase object to continue, $!."; + my $nb = $self->{nodebase} || croak "No nodebase. Need a nodebase to run tests."; my @nodes_under_test = (); foreach ( @@ -33,7 +68,7 @@ $self->{mock} = $mock; } - + sub pretest_setup : Test(setup) { my $self = shift; @@ -130,11 +165,6 @@ my @nodes = @{ $self->{nodes_under_test} }; $self->num_tests( scalar @nodes ); - local *Everything::HTML::logErrors; - local *Everything::logErrors; - my $err = ''; - *Everything::HTML::logErrors = sub { $err .= "@_"; }; - *Everything::logErrors = sub { $err .= "@_"; }; my %successful_nodes; foreach (@nodes) { @@ -167,31 +197,16 @@ my @nodes_to_test = grep { $$compilable{ $_->{node_id} } } @$test_nodes; $self->num_tests( scalar(@nodes_to_test) * 2 ); - local *Everything::HTML::logErrors; - local *Everything::logErrors; - - my $err; - - my $error_code = sub { - my ( $warn, $error, $text, $node ) = @_; - $err .= join "\n", $warn, $error, $text, $$node{title}; - $err .= "\n" . '#' x 30; - $err .= "\n\n"; - }; - - *Everything::HTML::logErrors = $error_code; - *Everything::logErrors = $error_code; - $mock->{node_id} = 123; $mock->{to_node} = 456; my @args; foreach (@nodes_to_test) { - $err = ''; my $node = $self->{nodebase}->getNode($_); - diag "\nNow testing htmlcode named '$$node{title}'.\n\n"; + $err = []; + my @args = (); if ( $$node{title} eq 'formatCols' ) { @@ -200,10 +215,9 @@ my $ehtml = Everything::HTML->new( { request => $mock } ); my $rv = $node->run( { args => \@args, ehtml => $ehtml } ); - ok( !$err, -"...execute node $$node{title}, type $$node{type}{title}, id, $$node{node_id}" - ) || diag $err; + test_node_error( $node ); + my $linter = HTML::Lint->new; $linter->only_types( 'HTML::Lint::Error::HELPER', 'HTML::Lint::Error::FLUFF' ) @@ -233,35 +247,20 @@ my @nodes_to_test = grep { $$compilable{ $_->{node_id} } } @$test_nodes; $self->num_tests( scalar(@nodes_to_test) ); - local *Everything::HTML::logErrors; - local *Everything::logErrors; - - my $err; - - my $error_code = sub { - my ( $warn, $error, $text, $node ) = @_; - $err .= join "\n", $warn, $error, $text, $$node{title}; - $err .= "\n" . '#' x 30; - $err .= "\n\n"; - }; - - *Everything::HTML::logErrors = $error_code; - *Everything::logErrors = $error_code; - $mock->{group} = []; foreach (@nodes_to_test) { $err = ''; $Everything::HTML::GNODE = $mock; my $node = $self->{nodebase}->getNode($_); - diag "\nNow testing 'opcode' named '$$node{title}'.\n\n"; + my @args = (); # opcodes are only passed the request object as the only argument my $rv = $node->run( { args => [$mock] } ); - ok( !$err, -"...execute node $$node{title}, type $$node{type}{title}, id, $$node{node_id}" - ) || diag $err; + + test_node_error( $node ); + } } @@ -351,42 +350,26 @@ my @nodes_to_test = grep { $$compilable{ $_->{node_id} } } @$test_nodes; $self->num_tests( scalar(@nodes_to_test) * 10 ); - local *Everything::HTML::logErrors; - local *Everything::logErrors; - - my $err; - - my $error_code = sub { - my ( $warn, $error, $text, $node ) = @_; - $err .= join "\n", $warn, $error, $text, $$node{title}; - $err .= "\n" . '#' x 30; - $err .= "\n\n"; - }; - - *Everything::HTML::logErrors = $error_code; - *Everything::logErrors = $error_code; - my $setup_parser = setup_parser(); foreach (@nodes_to_test) { - $err = ''; + my $node = $self->{nodebase}->getNode($_); - diag "\nNow testing $nodetype named '$$node{title}'.\n\n"; - foreach my $parsetype (qw/TEXT PERL HTMLCODE HTMLSNIPPET ALL/) { + $err = []; + $setup_parser->( $parsetype, $node ); my @args = (); my $ehtml = Everything::HTML->new( { request => $mock } ); my $rv = $node->run( { args => \@args, ehtml => $ehtml } ); - ok( !$err, -"...execute node $$node{title}, type $$node{type}{title}, id, $$node{node_id}" - ) || diag $err; + test_node_error( $node ); + my $linter = HTML::Lint->new; $filterlinter_cb->( $linter, $node ) if $filterlinter_cb; $linter->parse($rv); Modified: trunk/ebase/lib/Everything/Test/Ecore/Install.pm =================================================================== --- trunk/ebase/lib/Everything/Test/Ecore/Install.pm 2008-10-15 20:15:59 UTC (rev 1015) +++ trunk/ebase/lib/Everything/Test/Ecore/Install.pm 2008-10-15 21:28:26 UTC (rev 1016) @@ -2,7 +2,11 @@ package Everything::Test::Ecore::Install; use Everything::NodeBase; +use Everything::Install; use Everything::Storage::Nodeball; +use Everything::DB::mysql; +use Everything::DB::Pg; +use Everything::DB::sqlite; use Carp qw/confess cluck croak/; use Test::More; use base 'Test::Class'; @@ -10,6 +14,57 @@ use strict; use warnings; +sub SKIP_CLASS { + my $self = shift; + my $class = ref $self ? ref $self : $self; + $class->SUPER( @_ ); +} + +sub startup :Test(startup) { + my $self = shift; + + my $config = $self->{ config }; + + my $ball = $self->{ nodeball }; + + my $opts = $self->{ opts } || {}; + + my $installer = Everything::Install->new; + + $installer->set_nodeball( Everything::Storage::Nodeball->new( nodeball => $ball ) ); + + if ( $config ) { + + $$opts{ type } = $config->database_type; + $$opts{ user } = $config->database_user; + $$opts{ database } = $config->database_name; + $$opts{ password } = $config->database_password; + $$opts{ db_rootuser } = $config->database_superuser; + $$opts{ db_rootpass } = $config->database_superpassword; + + } + + + if ( "Everything::DB::$$opts{ type }"->databaseExists( map { defined $_ ? $_ : '' } @$opts{ qw/database db_rootuser db_rootpass host port/ } ) ) { + diag "Database $$opts{ database } exists will try to drop...."; + if (! "Everything::DB::$$opts{ type }"->drop_database( map { defined $_ ? $_ : '' } @$opts{ qw/database db_rootuser db_rootpass host port/ } ) ) { + $self->BAILOUT( "... drop database failed, bailing."); + } else { + diag "...drop database succeeded. Continuing."; + } + } + + + $installer->create_storage( $opts ); + + my $nb = $installer->get_nodebase; + + $self->{nb} = $nb; + $self->{db_type} = $$opts{ type }; + $self->{installer} = $installer; + +} + sub test_10_sql_tables : Test(1) { my $self = shift; Modified: trunk/ebase/lib/Everything/Test/HTML.pm =================================================================== --- trunk/ebase/lib/Everything/Test/HTML.pm 2008-10-15 20:15:59 UTC (rev 1015) +++ trunk/ebase/lib/Everything/Test/HTML.pm 2008-10-15 21:28:26 UTC (rev 1016) @@ -32,6 +32,8 @@ $mock->fake_module('Everything::Auth'); $mock->fake_module( 'Everything', logErrors => sub { push @le, [@_] } ); + $mock->set_true( qw/get_user set_message/ ); + $self->{mock} = $mock; $self->{class} = $class; use_ok($class) or die; @@ -565,7 +567,7 @@ my $package = $self->{class}; my $mock = $self->mock_everything_request; - + $mock->set_true('set_message'); $mock->{node_id} = 999; #prevents warning; $mock->set_always( -isGod => 'randomdata' ); my $list_flag = 0; Modified: trunk/ebase/lib/Everything/Test/NodeBase.pm =================================================================== --- trunk/ebase/lib/Everything/Test/NodeBase.pm 2008-10-15 20:15:59 UTC (rev 1015) +++ trunk/ebase/lib/Everything/Test/NodeBase.pm 2008-10-15 21:28:26 UTC (rev 1016) @@ -8,6 +8,7 @@ use Test::More; use Test::MockObject; use Test::MockObject::Extends; +use Test::Warn; use Scalar::Util 'blessed'; @@ -124,7 +125,7 @@ '... reblessing into workspace package' ); } -sub test_build_nodetype_modules :Test( 2 ) +sub test_build_nodetype_modules :Test( 3 ) { my $self = shift; my $nb = $self->{nb}; @@ -137,7 +138,9 @@ ); $storage->set_always( getFieldsHash => '' ); - my $result = $nb->buildNodetypeModules(); + my $result; + + warning_like { $result = $nb->buildNodetypeModules() } qr/no such nodetype/i; is( keys %$result, 3, 'buildNodetypeModules() should return a hash ref' ); is_deeply( $result, Added: trunk/ebase/t/ecore/Pg/010-install.t =================================================================== --- trunk/ebase/t/ecore/Pg/010-install.t (rev 0) +++ trunk/ebase/t/ecore/Pg/010-install.t 2008-10-15 21:28:26 UTC (rev 1016) @@ -0,0 +1,27 @@ +#!/usr/bin/perl + +use lib 't/lib'; +use DBTestUtil qw/config_file skip_cond/; +use Everything::Test::Ecore::Install; +use Everything::Config; +use Everything::CmdLine qw/abs_path/; +use strict; +use warnings; + +my $ball = '../ecore'; + +my $config_file = config_file(); + +my @config_args; + +push @config_args, file => $config_file if -e $config_file; + +my $skip = skip_cond(); + +Everything::Test::Ecore::Install->SKIP_CLASS( $skip ) if $skip; + +my $config = Everything::Config->new( @config_args ); + +my $tests = Everything::Test::Ecore::Install->new( nodeball => abs_path( $ball ), config => $config ); + +$tests->runtests; Property changes on: trunk/ebase/t/ecore/Pg/010-install.t ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: trunk/ebase/t/ecore/Pg/020-compile.t =================================================================== --- trunk/ebase/t/ecore/Pg/020-compile.t (rev 0) +++ trunk/ebase/t/ecore/Pg/020-compile.t 2008-10-15 21:28:26 UTC (rev 1016) @@ -0,0 +1,23 @@ +#!/usr/bin/perl + +use lib 't/lib'; +use Everything::Test::Ecore::Compile; +use DBTestUtil qw/skip_cond nodebase/; +use Test::More; +use strict; +use warnings; + +use Carp; + +my $skip = skip_cond(); +my $nodebase; + +if ( $skip ) { + Everything::Test::Ecore::Compile->SKIP_CLASS( $skip ); +} else { + $nodebase = nodebase(); +} + +my $tests = Everything::Test::Ecore::Compile->new( nodebase => $nodebase ); + +$tests->runtests; Property changes on: trunk/ebase/t/ecore/Pg/020-compile.t ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: trunk/ebase/t/ecore/Pg/090-drop-database.t =================================================================== --- trunk/ebase/t/ecore/Pg/090-drop-database.t (rev 0) +++ trunk/ebase/t/ecore/Pg/090-drop-database.t 2008-10-15 21:28:26 UTC (rev 1016) @@ -0,0 +1,13 @@ +#!/usr/bin/perl + +use lib 't/lib'; +use DBTestUtil qw/drop_database skip_cond/; +use Test::More; + +if ( my $skip = skip_cond() ) { + plan skip_all => $skip; +} else { + plan tests => 1; +} + +ok( drop_database(), '...drops the test database.' ); Property changes on: trunk/ebase/t/ecore/Pg/090-drop-database.t ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: trunk/ebase/t/ecore/mysql/010-install.t =================================================================== --- trunk/ebase/t/ecore/mysql/010-install.t (rev 0) +++ trunk/ebase/t/ecore/mysql/010-install.t 2008-10-15 21:28:26 UTC (rev 1016) @@ -0,0 +1,27 @@ +#!/usr/bin/perl + +use lib 't/lib'; +use DBTestUtil qw/config_file skip_cond/; +use Everything::Test::Ecore::Install; +use Everything::Config; +use Everything::CmdLine qw/abs_path/; +use strict; +use warnings; + +my $ball = '../ecore'; + +my $config_file = config_file(); + +my @config_args; + +push @config_args, file => $config_file if -e $config_file; + +my $skip = skip_cond(); + +Everything::Test::Ecore::Install->SKIP_CLASS( $skip ) if $skip; + +my $config = Everything::Config->new( @config_args ); + +my $tests = Everything::Test::Ecore::Install->new( nodeball => abs_path( $ball ), config => $config ); + +$tests->runtests; Property changes on: trunk/ebase/t/ecore/mysql/010-install.t ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: trunk/ebase/t/ecore/mysql/020-compile.t =================================================================== --- trunk/ebase/t/ecore/mysql/020-compile.t (rev 0) +++ trunk/ebase/t/ecore/mysql/020-compile.t 2008-10-15 21:28:26 UTC (rev 1016) @@ -0,0 +1,23 @@ +#!/usr/bin/perl + +use lib 't/lib'; +use Everything::Test::Ecore::Compile; +use DBTestUtil qw/skip_cond nodebase/; +use Test::More; +use strict; +use warnings; + +use Carp; + +my $skip = skip_cond(); +my $nodebase; + +if ( $skip ) { + Everything::Test::Ecore::Compile->SKIP_CLASS( $skip ); +} else { + $nodebase = nodebase(); +} + +my $tests = Everything::Test::Ecore::Compile->new( nodebase => $nodebase ); + +$tests->runtests; Property changes on: trunk/ebase/t/ecore/mysql/020-compile.t ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: trunk/ebase/t/ecore/mysql/090-drop-database.t =================================================================== --- trunk/ebase/t/ecore/mysql/090-drop-database.t (rev 0) +++ trunk/ebase/t/ecore/mysql/090-drop-database.t 2008-10-15 21:28:26 UTC (rev 1016) @@ -0,0 +1,13 @@ +#!/usr/bin/perl + +use lib 't/lib'; +use DBTestUtil qw/drop_database skip_cond/; +use Test::More; + +if ( my $skip = skip_cond() ) { + plan skip_all => $skip; +} else { + plan tests => 1; +} + +ok( drop_database(), '...drops the test database.' ); Property changes on: trunk/ebase/t/ecore/mysql/090-drop-database.t ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: trunk/ebase/t/ecore/sqlite/010-install.t =================================================================== --- trunk/ebase/t/ecore/sqlite/010-install.t (rev 0) +++ trunk/ebase/t/ecore/sqlite/010-install.t 2008-10-15 21:28:26 UTC (rev 1016) @@ -0,0 +1,27 @@ +#!/usr/bin/perl + +use lib 't/lib'; +use DBTestUtil qw/config_file skip_cond/; +use Everything::Test::Ecore::Install; +use Everything::Config; +use Everything::CmdLine qw/abs_path/; +use strict; +use warnings; + +my $ball = '../ecore'; + +my $config_file = config_file(); + +my @config_args; + +push @config_args, file => $config_file if -e $config_file; + +my $skip = skip_cond(); + +Everything::Test::Ecore::Install->SKIP_CLASS( $skip ) if $skip; + +my $config = Everything::Config->new( @config_args ); + +my $tests = Everything::Test::Ecore::Install->new( nodeball => abs_path( $ball ), config => $config ); + +$tests->runtests; Property changes on: trunk/ebase/t/ecore/sqlite/010-install.t ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: trunk/ebase/t/ecore/sqlite/020-compile.t =================================================================== --- trunk/ebase/t/ecore/sqlite/020-compile.t (rev 0) +++ trunk/ebase/t/ecore/sqlite/020-compile.t 2008-10-15 21:28:26 UTC (rev 1016) @@ -0,0 +1,23 @@ +#!/usr/bin/perl + +use lib 't/lib'; +use Everything::Test::Ecore::Compile; +use DBTestUtil qw/skip_cond nodebase/; +use Test::More; +use strict; +use warnings; + +use Carp; + +my $skip = skip_cond(); +my $nodebase; + +if ( $skip ) { + Everything::Test::Ecore::Compile->SKIP_CLASS( $skip ); +} else { + $nodebase = nodebase(); +} + +my $tests = Everything::Test::Ecore::Compile->new( nodebase => $nodebase ); + +$tests->runtests; Property changes on: trunk/ebase/t/ecore/sqlite/020-compile.t ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: trunk/ebase/t/ecore/sqlite/090-drop-database.t =================================================================== --- trunk/ebase/t/ecore/sqlite/090-drop-database.t (rev 0) +++ trunk/ebase/t/ecore/sqlite/090-drop-database.t 2008-10-15 21:28:26 UTC (rev 1016) @@ -0,0 +1,13 @@ +#!/usr/bin/perl + +use lib 't/lib'; +use DBTestUtil qw/drop_database skip_cond/; +use Test::More; + +if ( my $skip = skip_cond() ) { + plan skip_all => $skip; +} else { + plan tests => 1; +} + +ok( drop_database(), '...drops the test database.' ); Property changes on: trunk/ebase/t/ecore/sqlite/090-drop-database.t ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: trunk/ebase/t/lib/DBTestUtil.pm =================================================================== --- trunk/ebase/t/lib/DBTestUtil.pm (rev 0) +++ trunk/ebase/t/lib/DBTestUtil.pm 2008-10-15 21:28:26 UTC (rev 1016) @@ -0,0 +1,72 @@ +package DBTestUtil; + +use base 'Exporter'; +use Everything::Config; + +our @EXPORT_OK = qw/config_file drop_database skip_cond nodebase/; + + +sub config_file { + + my $db_type = db_type(); + return "t/lib/db/$db_type.conf"; + +} + +sub db_type { + + $0 =~ m|t/ecore/(.*?)/\d{3}\-[\w-]+\.t$|; + return $1; + +} + +sub drop_database { + + my $config_file = config_file(); + my $config = Everything::Config->new( file => $config_file ); + + my $storage_class = 'Everything::DB::' . $config->database_type; + + ( my $file = $storage_class ) =~ s/::/\//g; + $file .= '.pm'; + require $file; + + $storage_class->drop_database ( + $config->database_name, + $config->database_superuser, + $config->database_superpassword + ); + + +} + +sub skip_cond { + my ( $class ) = @_; + + my $run_tests = 't/lib/db/run-tests'; + + my $config_file = config_file(); + + my $msg = ''; + + + if ( ! -e $run_tests ) { + + return "Time consuming DB tests skipped by default. Touch '$run_tests' to run."; + + } elsif ( ! -e $config_file ) { + + return "The config file '$config_file' must exist to run these tests."; + } + + return; + +} + +sub nodebase { + + my $config = Everything::Config->new( file => config_file() ); + return $config->nodebase; + + +} Property changes on: trunk/ebase/t/lib/DBTestUtil.pm ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: trunk/ebase/t/lib/db/Pg.conf.template =================================================================== --- trunk/ebase/t/lib/db/Pg.conf.template (rev 0) +++ trunk/ebase/t/lib/db/Pg.conf.template 2008-10-15 21:28:26 UTC (rev 1016) @@ -0,0 +1,21 @@ +## To run postgres tests copy this to t/lib/db/Pg.conf and +## edit the following fields as required for your setup + +# The database superuser should have create role, grant privileges and +# create database privileges +database_superuser = +database_superpassword = + +## The name of the database we create to run the tests, you can change +## it if you need to +database_name = ecoretest + +## The name of the user that will be created by these tests +database_user = ecoretester +database_password = ecoretester + +## You shouldn't need to change this +database_type = Pg + + + Property changes on: trunk/ebase/t/lib/db/Pg.conf.template ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: trunk/ebase/t/lib/db/mysql.conf.template =================================================================== --- trunk/ebase/t/lib/db/mysql.conf.template (rev 0) +++ trunk/ebase/t/lib/db/mysql.conf.template 2008-10-15 21:28:26 UTC (rev 1016) @@ -0,0 +1,19 @@ +## Copy this file to t/lib/db/mysql.conf and edit it as require +## to run mysql database tetss + +# The database superuser should have privileges to create databases, +# users and grant privileges +database_superuser = +database_superpassword = + +## The name of the database and user that will be created, change it +## if it doesn't work with your setup +database_name = ecoretest + +## The database user and password, change it if it doesn't work for your setup +database_user = ecoretester +database_password = ecoretester + +## You probably won't need to amend this +database_type = mysql + Property changes on: trunk/ebase/t/lib/db/mysql.conf.template ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pau...@us...> - 2008-10-15 19:59:19
|
Revision: 1014 http://everydevel.svn.sourceforge.net/everydevel/?rev=1014&view=rev Author: paul_the_nomad Date: 2008-10-15 19:59:14 +0000 (Wed, 15 Oct 2008) Log Message: ----------- Changes to the response class interface Added response classes to allow the downloading of nodeballs. Modified Paths: -------------- trunk/ebase/TODO Modified: trunk/ebase/TODO =================================================================== --- trunk/ebase/TODO 2008-10-15 19:55:39 UTC (rev 1013) +++ trunk/ebase/TODO 2008-10-15 19:59:14 UTC (rev 1014) @@ -7,7 +7,15 @@ * Amend FromObject.pm so that form objects return labels with a 'for' attribute and id in the input tag. +<<<<<<< HEAD:ebase/TODO +======= +* Require Everything::HTML::Response classes to create certain HTTP headers + +* Everything::HTML::Response classes to return error values on error - + e.g. Forbidden +>>>>>>> Changes to the response class interface:ebase/TODO + * Change default DB (for all DBs) setup so default encoding is utf8 * Documentation - Ecore should be self documenting This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pau...@us...> - 2008-10-15 19:55:51
|
Revision: 1013 http://everydevel.svn.sourceforge.net/everydevel/?rev=1013&view=rev Author: paul_the_nomad Date: 2008-10-15 19:55:39 +0000 (Wed, 15 Oct 2008) Log Message: ----------- Fixes to make login node validate in xhtml and to ensure cloneNode asks for the correct superdoc. Modified Paths: -------------- trunk/ecore/nodes/htmlsnippet/stdstylesheet.xml Modified: trunk/ecore/nodes/htmlsnippet/stdstylesheet.xml =================================================================== --- trunk/ecore/nodes/htmlsnippet/stdstylesheet.xml 2008-09-05 11:00:17 UTC (rev 1012) +++ trunk/ecore/nodes/htmlsnippet/stdstylesheet.xml 2008-10-15 19:55:39 UTC (rev 1013) @@ -100,6 +100,11 @@ } +.loginnode label { +width: 6em; + +} + input label { float:right; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pau...@us...> - 2008-09-05 11:00:26
|
Revision: 1012 http://everydevel.svn.sourceforge.net/everydevel/?rev=1012&view=rev Author: paul_the_nomad Date: 2008-09-05 11:00:17 +0000 (Fri, 05 Sep 2008) Log Message: ----------- Capitalise nodelet titles. And codelisting in monospace rather than fixed. Modified Paths: -------------- trunk/ebase/TODO trunk/ecore/ME trunk/ecore/nodes/htmlpage/container_display_page.xml trunk/ecore/nodes/htmlsnippet/stdstylesheet.xml trunk/ecore/nodes/nodeletgroup/all_nodelets.xml trunk/ecore/nodes/nodeletgroup/default_nodelets.xml trunk/ecore/nodes/nodeletgroup/system_nodelets.xml Added Paths: ----------- trunk/ecore/nodes/nodelet/Admin_Nodelet.xml trunk/ecore/nodes/nodelet/Admin_Nodelet_Mini.xml trunk/ecore/nodes/nodelet/Personal_Nodelet.xml trunk/ecore/nodes/nodelet/Workspace_Info.xml Removed Paths: ------------- trunk/ecore/nodes/nodelet/admin_Nodelet_Mini.xml trunk/ecore/nodes/nodelet/admin_nodelet.xml trunk/ecore/nodes/nodelet/personal_nodelet.xml trunk/ecore/nodes/nodelet/workspace_info.xml Modified: trunk/ebase/TODO =================================================================== --- trunk/ebase/TODO 2008-07-12 11:56:47 UTC (rev 1011) +++ trunk/ebase/TODO 2008-09-05 11:00:17 UTC (rev 1012) @@ -8,11 +8,6 @@ * Amend FromObject.pm so that form objects return labels with a 'for' attribute and id in the input tag. -* Require Everything::HTML::Response classes to create certain HTTP headers - -* Everything::HTML::Response classes to return error values on error - - e.g. Forbidden - * Change default DB (for all DBs) setup so default encoding is utf8 * Documentation - Ecore should be self documenting @@ -49,4 +44,16 @@ This may involve creating objects that are a superclass of nodes, i.e. nodes are an 'object' and links are also 'objects', of making - links nodes. In the latter case, nodes will have to be slimmed down. \ No newline at end of file + links nodes. In the latter case, nodes will have to be slimmed + down. + +* Port enote and preview + +* Implement Captcha + + Get rid of comment spam + Probably use Authen::Captcha + +* Implement session keys + + Track user sessions deal with comment spam etc \ No newline at end of file Modified: trunk/ecore/ME =================================================================== --- trunk/ecore/ME 2008-07-12 11:56:47 UTC (rev 1011) +++ trunk/ecore/ME 2008-09-05 11:00:17 UTC (rev 1012) @@ -88,10 +88,10 @@ <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Other Users Mini</member> <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Server Statistics</member> <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Tick tock</member> - <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">admin Nodelet Mini</member> - <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">admin nodelet</member> - <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">personal nodelet</member> - <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">workspace info</member> + <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Admin Nodelet Mini</member> + <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Admin Nodelet</member> + <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Personal Nodelet</member> + <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Workspace Info</member> <member name="group_node" type="noderef" type_nodetype="mail,nodetype">New User Mail</member> <member name="group_node" type="noderef" type_nodetype="mail,nodetype">Password Mail</member> <member name="group_node" type="noderef" type_nodetype="location,nodetype">container</member> Modified: trunk/ecore/nodes/htmlpage/container_display_page.xml =================================================================== --- trunk/ecore/nodes/htmlpage/container_display_page.xml 2008-07-12 11:56:47 UTC (rev 1011) +++ trunk/ecore/nodes/htmlpage/container_display_page.xml 2008-09-05 11:00:17 UTC (rev 1012) @@ -24,7 +24,7 @@ my $DB = $this->get_nodebase; my %GLOBAL; -return $this->link_node->($$NODE{parent_container}) if $$NODE{parent_container}; +return $this->link_node($$NODE{parent_container}) if $$NODE{parent_container}; "<i>none</i>"; %] Modified: trunk/ecore/nodes/htmlsnippet/stdstylesheet.xml =================================================================== --- trunk/ecore/nodes/htmlsnippet/stdstylesheet.xml 2008-07-12 11:56:47 UTC (rev 1011) +++ trunk/ecore/nodes/htmlsnippet/stdstylesheet.xml 2008-09-05 11:00:17 UTC (rev 1012) @@ -180,7 +180,7 @@ } .listcode { -font-family: fixed; +font-family: monospace; font-size:12pt; width: 90%; border-width: 3px; Copied: trunk/ecore/nodes/nodelet/Admin_Nodelet.xml (from rev 1011, trunk/ecore/nodes/nodelet/admin_nodelet.xml) =================================================================== --- trunk/ecore/nodes/nodelet/Admin_Nodelet.xml (rev 0) +++ trunk/ecore/nodes/nodelet/Admin_Nodelet.xml 2008-09-05 11:00:17 UTC (rev 1012) @@ -0,0 +1,74 @@ +<NODE export_version="0.5" nodetype="nodelet" title="Admin Nodelet"> + <field name="author_user" type="noderef" type_nodetype="user,nodetype">root</field> + <field name="authoraccess" type="literal_value">-i-i</field> + <field name="dynamicauthor_permission" type="literal_value">0</field> + <field name="dynamicgroup_permission" type="literal_value">0</field> + <field name="dynamicguest_permission" type="literal_value">0</field> + <field name="dynamicother_permission" type="literal_value">-1</field> + <field name="group_usergroup" type="literal_value">-1</field> + <field name="groupaccess" type="literal_value">-i-i-</field> + <field name="guestaccess" type="literal_value">-i-i-</field> + <field name="loc_location" type="noderef" type_nodetype="location,nodetype">nodelet</field> + <field name="mini_nodelet" type="noderef" type_nodetype="nodelet,nodetype">Admin Nodelet Mini</field> + <field name="nlcode" type="literal_value"><table> + <tr style="padding: none"> + <td> +[% +my $query = $this->get_query; +my $str = $query->start_form("POST",$query->script_name); +$str .= $query->p( { style => 'line-height: 1.0' }, "node" . '&nbsp;' . + $query->textfield(-name => "node", -default => "", + -override => 1, -size => 10, -maxlength => 240) . + '&nbsp;' . + $this->submit ); + +$str .= $query->end_form; +%] + </td> + </tr> + <tr> + <td style="padding: none"> +[% +my $query = $this->get_query; +my $str = $query->start_form("POST",$query->script_name); +$str .= $query->p( { style => 'line-height: 1.0' }, "id &nbsp;" . + $query->textfield(-name => "node_id", + -default => "", -override => 1, -size => 10, + -maxlength => 240) . '&nbsp;'. + $this->submit ); + +$str .= $query->end_form; +%] + </td> + </tr> + <tr> + <td style="font-size: 110%"> +[% +my $NODE = $this->get_node; +my $query = $this->get_query; +my $str = "<a href="; +my $displaytype = $query->param('displaytype'); +$displaytype ||= 'display'; +$str .= $this->url_gen({ 'node_id' => $this->get_nodebase->getId($NODE), + 'displaytype' => $displaytype, + 'containers' => 'show'})." >Show containers</a>"; + +%]<br/> + + [% +$this->link_node($this->get_nodebase->getNode('create node', 'restricted_superdoc'), + 'Create new node'); +%]<br/> + Current node id: [% $this->get_node->get_node_id +%] + </td> + </tr> +</table> + +[<adminbox>]</field> + <field name="otheraccess" type="literal_value">-i-i-</field> + <field name="parent_container" type="noderef" type_nodetype="container,nodetype">general nodelet container</field> + <field name="title" type="literal_value">Admin Nodelet</field> + <field name="type_nodetype" type="noderef" type_nodetype="nodetype,nodetype">nodelet</field> + <field name="updateinterval" type="literal_value">0</field> +</NODE> Property changes on: trunk/ecore/nodes/nodelet/Admin_Nodelet.xml ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Copied: trunk/ecore/nodes/nodelet/Admin_Nodelet_Mini.xml (from rev 1011, trunk/ecore/nodes/nodelet/admin_Nodelet_Mini.xml) =================================================================== --- trunk/ecore/nodes/nodelet/Admin_Nodelet_Mini.xml (rev 0) +++ trunk/ecore/nodes/nodelet/Admin_Nodelet_Mini.xml 2008-09-05 11:00:17 UTC (rev 1012) @@ -0,0 +1,19 @@ +<NODE export_version="0.5" nodetype="nodelet" title="Admin Nodelet Mini"> + <field name="author_user" type="noderef" type_nodetype="user,nodetype">root</field> + <field name="authoraccess" type="literal_value">ii-i</field> + <field name="dynamicauthor_permission" type="literal_value">-1</field> + <field name="dynamicgroup_permission" type="literal_value">-1</field> + <field name="dynamicguest_permission" type="literal_value">-1</field> + <field name="dynamicother_permission" type="literal_value">-1</field> + <field name="group_usergroup" type="literal_value">-1</field> + <field name="groupaccess" type="literal_value">ii-i-</field> + <field name="guestaccess" type="literal_value">ii-i-</field> + <field name="loc_location" type="noderef" type_nodetype="location,nodetype">nodelet</field> + <field name="mini_nodelet" type="noderef" type_nodetype="nodelet,nodetype">Admin Nodelet</field> + <field name="nlcode" type="literal_value">[<adminbox>]</field> + <field name="otheraccess" type="literal_value">ii-i-</field> + <field name="parent_container" type="noderef" type_nodetype="container,nodetype">general nodelet container</field> + <field name="title" type="literal_value">Admin Nodelet Mini</field> + <field name="type_nodetype" type="noderef" type_nodetype="nodetype,nodetype">nodelet</field> + <field name="updateinterval" type="literal_value">0</field> +</NODE> Property changes on: trunk/ecore/nodes/nodelet/Admin_Nodelet_Mini.xml ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Copied: trunk/ecore/nodes/nodelet/Personal_Nodelet.xml (from rev 1011, trunk/ecore/nodes/nodelet/personal_nodelet.xml) =================================================================== --- trunk/ecore/nodes/nodelet/Personal_Nodelet.xml (rev 0) +++ trunk/ecore/nodes/nodelet/Personal_Nodelet.xml 2008-09-05 11:00:17 UTC (rev 1012) @@ -0,0 +1,56 @@ +<NODE export_version="0.5" nodetype="nodelet" title="Personal Nodelet"> + <field name="author_user" type="noderef" type_nodetype="user,nodetype">root</field> + <field name="authoraccess" type="literal_value">iiii</field> + <field name="dynamicauthor_permission" type="literal_value">-1</field> + <field name="dynamicgroup_permission" type="literal_value">-1</field> + <field name="dynamicguest_permission" type="literal_value">-1</field> + <field name="dynamicother_permission" type="literal_value">-1</field> + <field name="group_usergroup" type="literal_value">-1</field> + <field name="groupaccess" type="literal_value">iiii-</field> + <field name="guestaccess" type="literal_value">iiii-</field> + <field name="loc_location" type="noderef" type_nodetype="location,nodetype">nodelet</field> + <field name="mini_nodelet" type="literal_value">0</field> + <field name="nlcode" type="literal_value">[% +my $NODE = $this->get_node; +my $USER = $this->get_user; +my $query = $this->get_query; +my $THEME = $this->get_theme; +my %HTMLVARS = %{ $this->get_htmlvars }; +my $VARS = $this->get_vars; +my $DB = $this->get_nodebase; +my %GLOBAL; + + + return if ($$USER{node_id} == $HTMLVARS{guest_user}); + my $limit = $HTMLVARS{personalNodeletLimit} || 10; + + my @nodes; + @nodes = split("<br>",$$VARS{personal_nodelet}) if ($$VARS{personal_nodelet}); + if (my $n = $query->param("addpersonalnodelet")) { + $n = $DB->getNodeById( $n ); + $$VARS{personal_nodelet} .= '<br>'.$$n{title} + if @nodes < $limit; + push @nodes, $$n{title}; + } + + + my $str; + my $i=0; + foreach (@nodes) { + $str.=$this->link_node_title($_)."<br>\n"; + last if $i++ >= 10; + } + + $str.="\n<p align=right>" + .$this->link_node($NODE, "add \"$$NODE{title}\"", {addpersonalnodelet => $NODE->get_node_id}) + if @nodes < $limit; + $str; + + +%]</field> + <field name="otheraccess" type="literal_value">iiii-</field> + <field name="parent_container" type="noderef" type_nodetype="container,nodetype">general nodelet container</field> + <field name="title" type="literal_value">Personal Nodelet</field> + <field name="type_nodetype" type="noderef" type_nodetype="nodetype,nodetype">nodelet</field> + <field name="updateinterval" type="literal_value">0</field> +</NODE> Property changes on: trunk/ecore/nodes/nodelet/Personal_Nodelet.xml ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Copied: trunk/ecore/nodes/nodelet/Workspace_Info.xml (from rev 1011, trunk/ecore/nodes/nodelet/workspace_info.xml) =================================================================== --- trunk/ecore/nodes/nodelet/Workspace_Info.xml (rev 0) +++ trunk/ecore/nodes/nodelet/Workspace_Info.xml 2008-09-05 11:00:17 UTC (rev 1012) @@ -0,0 +1,75 @@ +<NODE export_version="0.5" nodetype="nodelet" title="Workspace Info"> + <field name="author_user" type="noderef" type_nodetype="user,nodetype">root</field> + <field name="authoraccess" type="literal_value">iiii</field> + <field name="dynamicauthor_permission" type="literal_value">-1</field> + <field name="dynamicgroup_permission" type="literal_value">-1</field> + <field name="dynamicguest_permission" type="literal_value">-1</field> + <field name="dynamicother_permission" type="literal_value">-1</field> + <field name="group_usergroup" type="literal_value">-1</field> + <field name="groupaccess" type="literal_value">iiiii</field> + <field name="guestaccess" type="literal_value">iiiii</field> + <field name="loc_location" type="noderef" type_nodetype="location,nodetype">nodelet</field> + <field name="mini_nodelet" type="literal_value">0</field> + <field name="nlcode" type="literal_value">[% +my $NODE = $this->get_node; +my $USER = $this->get_user; +my $query = $this->get_query; +my $THEME = $this->get_theme; +my %HTMLVARS = %{ $this->get_htmlvars }; +my $VARS = $this->get_vars; +my $DB = $this->get_nodebase; +my %GLOBAL; + + +my $wspace = 0; +my $str; +$wspace = $DB->{workspace}{node_id} if exists $DB->{workspace}; + +my $csr = $DB->sqlSelectMany("inside_workspace", "revision", "node_id=$$NODE{node_id}"); +my %WSPACES; +while ($csr and my ($ws) = $csr->fetchrow) { + next if not $ws; + next if $ws == $wspace; + next if $WSPACES{$ws} == 1; + $WSPACES{$ws} = 1; + $str.= "This node is in workspace ".$this->link_node($ws)."<br>"; +} +$str.="Editing it may cause corruption<br>" if $str; +$str; + +%][% +my $NODE = $this->get_node; +my $USER = $this->get_user; +my $query = $this->get_query; +my $THEME = $this->get_theme; +my %HTMLVARS = %{ $this->get_htmlvars }; +my $VARS = $this->get_vars; +my $DB = $this->get_nodebase; +my %GLOBAL; + + +return "Not in workspace" unless $DB->{workspace} and $DB->{workspace}{title}; +my $str; + +$str.="You are in workspace ".linkNode($DB->{workspace}); +$str.="<p><b>This node can not be put in workspace</b>" unless $NODE->canWorkspace(); + +if (exists $DB->{workspace}{nodes}{$$NODE{node_id}}) { + $str.="<p>This node is inside your workspace:"; + $str.="<br>".linkNode($NODE, "Commit", { op=> 'commitworkspace', + "commit_$$NODE{node_id}" => 'commit', + workspace_id => $DB->{workspace}{node_id}}). " changes"; + $str.="<br>".linkNode($NODE, "Discard", { op => 'commitworkspace', + "commit_$$NODE{node_id}" => 'discard', + workspace_id => $DB->{workspace}{node_id}}). " changes"; +} + +$str; + +%]</field> + <field name="otheraccess" type="literal_value">iiiii</field> + <field name="parent_container" type="noderef" type_nodetype="container,nodetype">general nodelet container</field> + <field name="title" type="literal_value">Workspace Info</field> + <field name="type_nodetype" type="noderef" type_nodetype="nodetype,nodetype">nodelet</field> + <field name="updateinterval" type="literal_value">0</field> +</NODE> Property changes on: trunk/ecore/nodes/nodelet/Workspace_Info.xml ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Deleted: trunk/ecore/nodes/nodelet/admin_Nodelet_Mini.xml =================================================================== --- trunk/ecore/nodes/nodelet/admin_Nodelet_Mini.xml 2008-07-12 11:56:47 UTC (rev 1011) +++ trunk/ecore/nodes/nodelet/admin_Nodelet_Mini.xml 2008-09-05 11:00:17 UTC (rev 1012) @@ -1,19 +0,0 @@ -<NODE export_version="0.5" nodetype="nodelet" title="admin Nodelet Mini"> - <field name="author_user" type="noderef" type_nodetype="user,nodetype">root</field> - <field name="authoraccess" type="literal_value">ii-i</field> - <field name="dynamicauthor_permission" type="literal_value">-1</field> - <field name="dynamicgroup_permission" type="literal_value">-1</field> - <field name="dynamicguest_permission" type="literal_value">-1</field> - <field name="dynamicother_permission" type="literal_value">-1</field> - <field name="group_usergroup" type="literal_value">-1</field> - <field name="groupaccess" type="literal_value">ii-i-</field> - <field name="guestaccess" type="literal_value">ii-i-</field> - <field name="loc_location" type="noderef" type_nodetype="location,nodetype">nodelet</field> - <field name="mini_nodelet" type="noderef" type_nodetype="nodelet,nodetype">admin nodelet</field> - <field name="nlcode" type="literal_value">[<adminbox>]</field> - <field name="otheraccess" type="literal_value">ii-i-</field> - <field name="parent_container" type="noderef" type_nodetype="container,nodetype">general nodelet container</field> - <field name="title" type="literal_value">admin Nodelet Mini</field> - <field name="type_nodetype" type="noderef" type_nodetype="nodetype,nodetype">nodelet</field> - <field name="updateinterval" type="literal_value">0</field> -</NODE> Deleted: trunk/ecore/nodes/nodelet/admin_nodelet.xml =================================================================== --- trunk/ecore/nodes/nodelet/admin_nodelet.xml 2008-07-12 11:56:47 UTC (rev 1011) +++ trunk/ecore/nodes/nodelet/admin_nodelet.xml 2008-09-05 11:00:17 UTC (rev 1012) @@ -1,74 +0,0 @@ -<NODE export_version="0.5" nodetype="nodelet" title="admin nodelet"> - <field name="author_user" type="noderef" type_nodetype="user,nodetype">root</field> - <field name="authoraccess" type="literal_value">-i-i</field> - <field name="dynamicauthor_permission" type="literal_value">0</field> - <field name="dynamicgroup_permission" type="literal_value">0</field> - <field name="dynamicguest_permission" type="literal_value">0</field> - <field name="dynamicother_permission" type="literal_value">-1</field> - <field name="group_usergroup" type="literal_value">-1</field> - <field name="groupaccess" type="literal_value">-i-i-</field> - <field name="guestaccess" type="literal_value">-i-i-</field> - <field name="loc_location" type="noderef" type_nodetype="location,nodetype">nodelet</field> - <field name="mini_nodelet" type="noderef" type_nodetype="nodelet,nodetype">admin Nodelet Mini</field> - <field name="nlcode" type="literal_value"><table> - <tr style="padding: none"> - <td> -[% -my $query = $this->get_query; -my $str = $query->start_form("POST",$query->script_name); -$str .= $query->p( { style => 'line-height: 1.0' }, "node" . '&nbsp;' . - $query->textfield(-name => "node", -default => "", - -override => 1, -size => 10, -maxlength => 240) . - '&nbsp;' . - $this->submit ); - -$str .= $query->end_form; -%] - </td> - </tr> - <tr> - <td style="padding: none"> -[% -my $query = $this->get_query; -my $str = $query->start_form("POST",$query->script_name); -$str .= $query->p( { style => 'line-height: 1.0' }, "id &nbsp;" . - $query->textfield(-name => "node_id", - -default => "", -override => 1, -size => 10, - -maxlength => 240) . '&nbsp;'. - $this->submit ); - -$str .= $query->end_form; -%] - </td> - </tr> - <tr> - <td style="font-size: 110%"> -[% -my $NODE = $this->get_node; -my $query = $this->get_query; -my $str = "<a href="; -my $displaytype = $query->param('displaytype'); -$displaytype ||= 'display'; -$str .= $this->url_gen({ 'node_id' => $this->get_nodebase->getId($NODE), - 'displaytype' => $displaytype, - 'containers' => 'show'})." >Show containers</a>"; - -%]<br/> - - [% -$this->link_node($this->get_nodebase->getNode('create node', 'restricted_superdoc'), - 'Create new node'); -%]<br/> - Current node id: [% $this->get_node->get_node_id -%] - </td> - </tr> -</table> - -[<adminbox>]</field> - <field name="otheraccess" type="literal_value">-i-i-</field> - <field name="parent_container" type="noderef" type_nodetype="container,nodetype">general nodelet container</field> - <field name="title" type="literal_value">admin nodelet</field> - <field name="type_nodetype" type="noderef" type_nodetype="nodetype,nodetype">nodelet</field> - <field name="updateinterval" type="literal_value">0</field> -</NODE> Deleted: trunk/ecore/nodes/nodelet/personal_nodelet.xml =================================================================== --- trunk/ecore/nodes/nodelet/personal_nodelet.xml 2008-07-12 11:56:47 UTC (rev 1011) +++ trunk/ecore/nodes/nodelet/personal_nodelet.xml 2008-09-05 11:00:17 UTC (rev 1012) @@ -1,56 +0,0 @@ -<NODE export_version="0.5" nodetype="nodelet" title="personal nodelet"> - <field name="author_user" type="noderef" type_nodetype="user,nodetype">root</field> - <field name="authoraccess" type="literal_value">iiii</field> - <field name="dynamicauthor_permission" type="literal_value">-1</field> - <field name="dynamicgroup_permission" type="literal_value">-1</field> - <field name="dynamicguest_permission" type="literal_value">-1</field> - <field name="dynamicother_permission" type="literal_value">-1</field> - <field name="group_usergroup" type="literal_value">-1</field> - <field name="groupaccess" type="literal_value">iiii-</field> - <field name="guestaccess" type="literal_value">iiii-</field> - <field name="loc_location" type="noderef" type_nodetype="location,nodetype">nodelet</field> - <field name="mini_nodelet" type="literal_value">0</field> - <field name="nlcode" type="literal_value">[% -my $NODE = $this->get_node; -my $USER = $this->get_user; -my $query = $this->get_query; -my $THEME = $this->get_theme; -my %HTMLVARS = %{ $this->get_htmlvars }; -my $VARS = $this->get_vars; -my $DB = $this->get_nodebase; -my %GLOBAL; - - - return if ($$USER{node_id} == $HTMLVARS{guest_user}); - my $limit = $HTMLVARS{personalNodeletLimit} || 10; - - my @nodes; - @nodes = split("<br>",$$VARS{personal_nodelet}) if ($$VARS{personal_nodelet}); - if (my $n = $query->param("addpersonalnodelet")) { - $n = $DB->getNodeById( $n ); - $$VARS{personal_nodelet} .= '<br>'.$$n{title} - if @nodes < $limit; - push @nodes, $$n{title}; - } - - - my $str; - my $i=0; - foreach (@nodes) { - $str.=$this->link_node_title($_)."<br>\n"; - last if $i++ >= 10; - } - - $str.="\n<p align=right>" - .$this->link_node($NODE, "add \"$$NODE{title}\"", {addpersonalnodelet => $NODE->get_node_id}) - if @nodes < $limit; - $str; - - -%]</field> - <field name="otheraccess" type="literal_value">iiii-</field> - <field name="parent_container" type="noderef" type_nodetype="container,nodetype">general nodelet container</field> - <field name="title" type="literal_value">personal nodelet</field> - <field name="type_nodetype" type="noderef" type_nodetype="nodetype,nodetype">nodelet</field> - <field name="updateinterval" type="literal_value">0</field> -</NODE> Deleted: trunk/ecore/nodes/nodelet/workspace_info.xml =================================================================== --- trunk/ecore/nodes/nodelet/workspace_info.xml 2008-07-12 11:56:47 UTC (rev 1011) +++ trunk/ecore/nodes/nodelet/workspace_info.xml 2008-09-05 11:00:17 UTC (rev 1012) @@ -1,75 +0,0 @@ -<NODE export_version="0.5" nodetype="nodelet" title="workspace info"> - <field name="author_user" type="noderef" type_nodetype="user,nodetype">root</field> - <field name="authoraccess" type="literal_value">iiii</field> - <field name="dynamicauthor_permission" type="literal_value">-1</field> - <field name="dynamicgroup_permission" type="literal_value">-1</field> - <field name="dynamicguest_permission" type="literal_value">-1</field> - <field name="dynamicother_permission" type="literal_value">-1</field> - <field name="group_usergroup" type="literal_value">-1</field> - <field name="groupaccess" type="literal_value">iiiii</field> - <field name="guestaccess" type="literal_value">iiiii</field> - <field name="loc_location" type="noderef" type_nodetype="location,nodetype">nodelet</field> - <field name="mini_nodelet" type="literal_value">0</field> - <field name="nlcode" type="literal_value">[% -my $NODE = $this->get_node; -my $USER = $this->get_user; -my $query = $this->get_query; -my $THEME = $this->get_theme; -my %HTMLVARS = %{ $this->get_htmlvars }; -my $VARS = $this->get_vars; -my $DB = $this->get_nodebase; -my %GLOBAL; - - -my $wspace = 0; -my $str; -$wspace = $DB->{workspace}{node_id} if exists $DB->{workspace}; - -my $csr = $DB->sqlSelectMany("inside_workspace", "revision", "node_id=$$NODE{node_id}"); -my %WSPACES; -while ($csr and my ($ws) = $csr->fetchrow) { - next if not $ws; - next if $ws == $wspace; - next if $WSPACES{$ws} == 1; - $WSPACES{$ws} = 1; - $str.= "This node is in workspace ".$this->link_node($ws)."<br>"; -} -$str.="Editing it may cause corruption<br>" if $str; -$str; - -%][% -my $NODE = $this->get_node; -my $USER = $this->get_user; -my $query = $this->get_query; -my $THEME = $this->get_theme; -my %HTMLVARS = %{ $this->get_htmlvars }; -my $VARS = $this->get_vars; -my $DB = $this->get_nodebase; -my %GLOBAL; - - -return "Not in workspace" unless $DB->{workspace} and $DB->{workspace}{title}; -my $str; - -$str.="You are in workspace ".linkNode($DB->{workspace}); -$str.="<p><b>This node can not be put in workspace</b>" unless $NODE->canWorkspace(); - -if (exists $DB->{workspace}{nodes}{$$NODE{node_id}}) { - $str.="<p>This node is inside your workspace:"; - $str.="<br>".linkNode($NODE, "Commit", { op=> 'commitworkspace', - "commit_$$NODE{node_id}" => 'commit', - workspace_id => $DB->{workspace}{node_id}}). " changes"; - $str.="<br>".linkNode($NODE, "Discard", { op => 'commitworkspace', - "commit_$$NODE{node_id}" => 'discard', - workspace_id => $DB->{workspace}{node_id}}). " changes"; -} - -$str; - -%]</field> - <field name="otheraccess" type="literal_value">iiiii</field> - <field name="parent_container" type="noderef" type_nodetype="container,nodetype">general nodelet container</field> - <field name="title" type="literal_value">workspace info</field> - <field name="type_nodetype" type="noderef" type_nodetype="nodetype,nodetype">nodelet</field> - <field name="updateinterval" type="literal_value">0</field> -</NODE> Modified: trunk/ecore/nodes/nodeletgroup/all_nodelets.xml =================================================================== --- trunk/ecore/nodes/nodeletgroup/all_nodelets.xml 2008-07-12 11:56:47 UTC (rev 1011) +++ trunk/ecore/nodes/nodeletgroup/all_nodelets.xml 2008-09-05 11:00:17 UTC (rev 1012) @@ -6,7 +6,7 @@ <field name="dynamicguest_permission" type="literal_value">-1</field> <field name="dynamicother_permission" type="literal_value">-1</field> <group> - <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">admin nodelet</member> + <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Admin Nodelet</member> <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">CGI::param</member> <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Server Statistics</member> <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Other Users</member> Modified: trunk/ecore/nodes/nodeletgroup/default_nodelets.xml =================================================================== --- trunk/ecore/nodes/nodeletgroup/default_nodelets.xml 2008-07-12 11:56:47 UTC (rev 1011) +++ trunk/ecore/nodes/nodeletgroup/default_nodelets.xml 2008-09-05 11:00:17 UTC (rev 1012) @@ -11,7 +11,7 @@ <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Other Users</member> <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">New Nodes</member> <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Links</member> - <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">personal nodelet</member> + <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Personal Nodelet</member> </group> <field name="group_usergroup" type="literal_value">-1</field> <field name="groupaccess" type="literal_value">iiii-</field> Modified: trunk/ecore/nodes/nodeletgroup/system_nodelets.xml =================================================================== --- trunk/ecore/nodes/nodeletgroup/system_nodelets.xml 2008-07-12 11:56:47 UTC (rev 1011) +++ trunk/ecore/nodes/nodeletgroup/system_nodelets.xml 2008-09-05 11:00:17 UTC (rev 1012) @@ -6,8 +6,8 @@ <field name="dynamicguest_permission" type="literal_value">-1</field> <field name="dynamicother_permission" type="literal_value">-1</field> <group> - <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">workspace info</member> - <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">admin nodelet</member> + <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Workspace Info</member> + <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Admin Nodelet</member> <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Node Bucket</member> <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Epicenter</member> <member name="group_node" type="noderef" type_nodetype="nodelet,nodetype">Node Statistics</member> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pau...@us...>
<pau...@us...> - 2008-08-19 11:24:53
|
Hello all, Anyone got any thoughts on this: Writing those live database tests has been very good because it has got me to focus on what the database is actually doing and how we construct nodes. What's also clear to me is that Everything is using default settings as substituting for NULL. What this means is that we've in effect got a lot of nullable columns that don't really apply to all nodes. Many of these should be split out into their own tables and "left joins" used so that when an entry does't exist we get NULL returned. So, I think the following changes would be good: * delete 'hits' and 'reputation' We don't used these two at all in ecore. They seem redundant, I mean, does a container node really need a reputation? Do we need to count the hits when an admin is tweaking an htmlpage node? These should be added as part of a module hence I will add these to the TODO file * modified, loc_location and lockedby_user/locktime should be removed from the node table and reimplemented like this: CREATE TABLE modified ( node_id int8, date timestamp, FOREIGN KEY (node_id) REFERENCES node(node_id) ON DELETE CASCADE ) CREATE TABLE location ( node_id int4, loc_location int4 FOREIGN KEY (node_id) REFERENCES node(node_id) ON DELETE CASCADE, FOREIGN KEY (loc_location) REFEFENCES node(node_id) ON DELETE RESTRICT ) CREATE TABLE lock ( node_id int4, lockedby_user int4, locktime timestamp, FOREIGN KEY (node_id) REFERENCES node(node_id) ON DELETE CASCADE, FOREIGN KEY (lockedby_user) REFERENCES node(node_id) ON DELETE RESTRICT, ) * group_usergroup This is usually left at its default value '-1', therefore, IMHO should be shifted out to it own table * author_user This is one I'm confused about. Does a node really need an author? What if there is none? Do we default to root? If yes, do we enforce that on the DB level or on perl logic level. In other words if the author_user field is properly nullable it should be moved into its own table. If not, then it can stay where it is. At the moment, I'm leaving it where it is, only because deciding where it goes makes my brain hurt. * dynamic permissions are hardly ever used (although they are extremely cool). I think they should be deleted from the node table and reimplemented in their own table * permissions This has given me the greatest trouble. Each permission has three values (inherit, enable (overriding inherit), disable (overriding inherit)). At the moment there are four permission fields author, group, other, guest. Each have four permissions read, write, execute and delete. In addition there is a 'create' permission for group, other and delete. This create permission is obviously only relevant to nodetype nodes (i.e. such and such user has permission to create nodes of this type). Because of this, it should be implemented differently, because a node instance inheriting a 'create' permission makes no sense, imo. At the moment permissions are stored as a string. 'i' meaning inherited, and then one of r,w,x,d or c for enabled and '-' for disabled. I've been wondering whether there is a more compact way of implementing this. Because each permission has three possible values, first I thought of some modulo ternary arithmetic could do it so that each permission could be a series of ternary digits. 2021, (decimal 61) would mean that a node could be read and executed, but not deleted, and would there for be the equivalent of rix-, under the current system. So the permissions table would look something like this (excuse the pseudo-SQL): permissionclass char(5), #one of author, group, other, guest node_id int references node(node_id), permission int #the decimal number representing the ternary permissions PRIMARY KEY( node_id, permissionclass) But this means implementing ternary logic and some ternary to decimal conversion tools. Another way to do it would involve more joins (again please excuse the pseudo-SQL): permissionclass char(5), #one of author, group, other, guest permissiontype char(1) # one of r, w, d, x permission tinyint # either NULL, 1 or 0 node_id int references node(node_id), PRIMARY KEY( node_id, permissionclass, permissiontype) This would, of course, require more joins. The permssion field is a 'trit'. NULL means inherit, 0 'disable' and '1' enable. So, we still need ternary logic, but don't need the ternary to decimal converson (yay!), but need more joins (boo!). I have no idea how to proceed on this one. Any feedback more than welcome. Thanks Paul |
From: Paul <pau...@us...> - 2008-08-10 14:13:14
|
Hello, I've mentioned before how I want to look at changing the schema. In particular, I want to normalise it a bit and, for example, put the permissions and dynamic permissions into their own table. The node table is definitely not in 3rd normal form, but I don't think it's in 1st normal form either given that the permissions columns are 'repeating groups', IMHO. I also don't think it's in 2nd NF because most permissions values are repeated, this means that they are not dependent on the primary key, but on something else. In fact, they're dependent on the nodetype and hence on a relation. Pushing them out into their own table(s) means that we can also better ensure data consistency. Speaking of data consistency.... In my last email I mentioned trying to get SQL totally out of nodeballs, or at least out of ecore... (if nodeball authors want to tie their nodeballs to one DB, it's none of my business). I realised that I couldn't do this before writing some tests that test against a live DB. All our DB tests currently use mocking heavily, which is OK as far as it goes, but when push comes to shove you need to know that the database dependent sql you're sending to the DB actually works. As, I've been doing this, I've come up against that data consistency issue again. For example, each row on the group table points to two rows in the node table. This means that they're foreign keys, yet no foreign key constraint is enforced. As a result you can get hanging group table entries....I have two currently on one site, I'm running. On deletion of the relevant nodes, those rows in the group table should have been deleted. I don't know why they weren't, but they weren't. "ON DELETE CASCADE" would not have allowed these hanging foreign keys to exist. There are more examples of this sort of thing. I think when Everything is installed on Pg, these constraints should be enforced. As for MySQL, I think we should install as InnoDB and if someone wants to convert to MyISAM let them do it, but Everydevel should aim for some transactional integrity. So on to nodetypes... One table that is clearly not normalised is the setting table. Settings can include literal values that may either be integers or strings or they may a reference to an entry in the node table (i.e. a foreign key). That's three datatypes which are two too many for an easily workable solution. However, recently, I've tried to think of a way of implementing blog-style comment threads. The obvious way to do this would be to make each comment a 'node'. However, it didn't feel right and the reason was because the philosophy behind a node is that the author has some ownership over it and can edit it. Blog-style comments don't have this attribute. I then looked at one of the comment modules on Drupal did. The solution seems to be to have a 'comment thread' nodetype. Any node, can have a 'comment thread' attached to it. We don't know how long a comment thread is so it's an aggregation of a list of data. Actually, my comment thread is reasonably complex as I have three tables. One is the comment itself, one is the poster who is identified by his/her email and the third is a blacklist of IP addresses from which no posting is allowed. Which brings me back to settings. Settings are lists of data values, so they are a list type or a subclass of list. Don't you think? Paul |
From: <pau...@us...>
<pau...@us...> - 2008-07-27 20:32:26
|
Greetings! Brian Aker wrote: > Hi! > > On Jul 26, 2008, at 6:34 AM, Paul wrote: > >> Rather than all this mucking around with XML, it might be far better to >> have all nodeballs, or at least ecore, as an sqlite database. On > > I cannot decide on first read if this is brilliant, or just another tool > I cannot edit with a plain text file. > Well, actually that reason and also the fact you can't diff it easily is why it might not happen. My main aim for suggesting that ecore be stored as an sqlite file is that, we need to get more people interested in Everything and whilst coding in perl is really cool and stuff, there are far more people who can knock up a bit of css than they can hack some perl. So, I'm thinking it is away to make installation easier, so that people can start making funky themes as they do with wordpress. To help this process I was considering putting a bare Everything up somewhere and leaving it open so that the public could hack it. Of course, you'd often get idiots who'd delete the whole site, and worse, but with frequent enough DB dumps it might have been OK. Then I remembered that Everything has pure code all over ecore and the aforementioned idiots might have even more fun with system('rm -rf /') and similar. And whilst the apache user might not have that many priveleges it's still enough to cause havoc. But perhaps I could just leave the CSS file open or something.... Speaking of CSS one of the things that bugs me about it, and indeed, one of the things I find annoying about CMS's like wordpress, is that you end up with these huge CSS files in which it is impossible to find the bit you're looking for. I hear that sensible people split up their CSS files into manageable and bite-sized chunks. The question is how to do that with Everything. > I am not a fan of XML because of all of the escaping required. Me neither, but I don't dislike it as much as I dislike the DOM :) Cheers Paul |
From: Brian A. <br...@ta...> - 2008-07-26 18:10:16
|
Hi! On Jul 26, 2008, at 6:34 AM, Paul wrote: > Rather than all this mucking around with XML, it might be far better > to > have all nodeballs, or at least ecore, as an sqlite database. On I cannot decide on first read if this is brilliant, or just another tool I cannot edit with a plain text file. I am not a fan of XML because of all of the escaping required. For Slash we built our own system which worked well (but we had to maintain it ourselves). Cheers, -Brian -- _______________________________________________________ Brian "Krow" Aker, brian at tangent.org Seattle, Washington http://krow.net/ <-- Me http://tangent.org/ <-- Software _______________________________________________________ You can't grep a dead tree. |
From: Paul <pau...@us...> - 2008-07-26 13:34:11
|
Hello, As I wrote in my last email, I've been wanting to abstract out the much database stuff so that we don't have to have SQL in nodeballs. This should allow more flexibility in the db schema that can be used. It should also help people who develop a nodeball in one DB and then want to export it. The two most popular nodeballs were Ewiki and EnoteAndPreview. These both need updating to work with the new system and it would be better if all development could occur on a live system and then be exported. So far the development process has been: perl -I lib t/ecore/ecore-install.pl -d t/ecore.db ../ecore/ t/TEST -start-httpd Point browser to localhost:8529 and make changes perl -I lib bin/export_nodeball.pl -d t/ecore.db 'core system' ../ecore/ and then commit changes. Rather than all this mucking around with XML, it might be far better to have all nodeballs, or at least ecore, as an sqlite database. On installation, the nodes are then extracted from ecore.db and put into the production mysql or Pg database. For one this means that we are going from SQL to 'internal representation' to SQL rather than SQL to 'internal representation' to XML to XML/Node 'representation' to SQL. Bugs are less likely to creep in. It's also simpler. On something different, people have often compared Everything to blogging software. I think a much better comparison is to Drupal. So, I think that's the goal...to be better than Drupal. Cheers Paul |
From: <pau...@us...>
<pau...@us...> - 2008-07-14 07:51:50
|
Hello all, The changes I've recently checked in now ensure that Everydevel is xhtml compliant for all nodes with displaytype 'display'. I've also checked in some code that allows people to download nodeballs from the location /repositories/nodeballs/<node_id>. It's a bit slow and could deal with some caching after the first request. The 'Caching' I suggest is pretty simple, in that the temp file used persists until the nodeball itself is updated at which point we rebuild it. On a slightly related point, it might be a good idea to export nodeballs with the ending tgz rather than nbz, as many archive browsing programs complain that nbz is not a file type they support. Anyway, onto database issues. One issue with everything is the way that nodeballs contain sql. This sql is naturally database dependent and if I develop a nobeball in say sqlite and then want to import it into a pg database, I have trouble. The solution is a layer of abstraction so that the DB layer decides on the db schema and not the nodeball. An advantage that flows from this is that we can then optimise the db schema without breaking the front-end. The first step is to export enough data into the nodeball to allow the db tables to reconstructed. In order to do this I plan to add a new XML tag to nodetype nodes when they are exported. I suggest calling it classdata. So it would be something like this: <classdata type="attribute"> <attribute type="name">attribute_name</attribute> <attribute type="type">int</attribute> <attribute type="length">8</attribute> <attribute type="nullable">no</attribute> </classdata> <classdata type="constraint"> <constraint type="primary_key">attribute_id</constraint> <constraint type="foreign_key" references="other_table">other_id</constraint> </classdata> So, for example here we've got enough data to recreate a column in sql: attribute_name int8 NOT NULL And then later on: alter table table_name add primary key(attribute_id); alter table table_name add constraint foreign key(other_id) references .... and so on. This allows us to export more data than we need. For example, foreign key constraints, which at the option of the DB layer may be ignored or not depending on the schema and db. To construct such fields, DBI provides the column_info method which returns way more than we need for this. For sqlite, column_info isn't supported but we can get the same sort of data from the PRAGMA command. One more thing on NOT NULL constraints. Everything is currently initialised with almost all fields constrained with NOT NULL. I can understand why this is in that it is really painful for the apache log to be littered with 'uninitialized value' warnings when it pulls a null value from the database. However, I believe it is for the front-end to deal with this scenario (by converting nulls to '' or throwing them away or whatever) and not for the DB layer. NULL is a valuable value. I've already come across a situation where it would be better for the modified field to default to NULL, rather than 0000-00-00 or -infinity, to mean 'never modified'. Besides that there is an important distinction between NULL and ''. One which means the value is not set and the other that it has been set to an empty string. The front-end may need to handle these to situations differently. So, I intend to remove all the NOT NULL constraints in the not too distant future. Any thoughts? Cheers Paul |
From: <pau...@us...> - 2008-07-12 11:56:54
|
Revision: 1011 http://everydevel.svn.sourceforge.net/everydevel/?rev=1011&view=rev Author: paul_the_nomad Date: 2008-07-12 04:56:47 -0700 (Sat, 12 Jul 2008) Log Message: ----------- Nodeball response type Added Paths: ----------- trunk/ebase/lib/Everything/HTTP/Response/Nodeball.pm trunk/ebase/lib/Everything/HTTP/Response/Test/Nodeball.pm trunk/ebase/t/nodeball-responder.t Added: trunk/ebase/lib/Everything/HTTP/Response/Nodeball.pm =================================================================== --- trunk/ebase/lib/Everything/HTTP/Response/Nodeball.pm (rev 0) +++ trunk/ebase/lib/Everything/HTTP/Response/Nodeball.pm 2008-07-12 11:56:47 UTC (rev 1011) @@ -0,0 +1,106 @@ +package Everything::HTTP::Response::Nodeball; + +use Everything::Storage::Nodeball; +use Apache2::Const qw/FORBIDDEN OK/; +use File::Temp qw/ :seekable /; +use strict; + +use base 'Class::Accessor::Fast'; +__PACKAGE__->follow_best_practice; +__PACKAGE__->mk_accessors( + qw/request headers/); +use strict; +use warnings; + +sub new { + my $class = shift; + my $self = bless {}, $class; + $self->init(@_); +} + +sub init { + my ( $self, $args ) = @_; + $self->set_request( $args->{ request } ); + $self->authorise; + $self->{ headers } = {}; + return $self; +} + +sub authorise { + my $self = shift; + my $e = $self->get_request; + my $user = $e->get_user; + my $node = $e->get_node; + return $self->allowed( 1 ) if $node->hasAccess( $user, 'r' ); + return $self->allowed( undef ); + +} + +sub content { + + my $self = shift; + return unless $self->allowed; + my $e = $self->get_request; + my $nb = $e->get_nodebase; + my $node = $e->get_node; + my $file = File::Temp->new; + + my $ball_title = $node->get_title; + + my $storage = Everything::Storage::Nodeball->new ( nodebase => $nb ); + + $storage->cleanup( 1 ); + $storage->export_nodeball_to_file( $ball_title, "$file" ); + + $ball_title =~ s/[^\w\.\-]/-/g; + $self->add_header( 'Content-Disposition', "attachment; filename=" . $ball_title . '.nbz' ); + + $file->seek( SEEK_SET, 0 ); + local $/; + return <$file>; +} + +sub headers { + + return %{ $_[0]->get_headers }; + +} + +sub content_type { + +'application/x-gzip'; + +} + +sub status_code { + my $self = shift; + return OK if $self->allowed; + return FORBIDDEN; + +} + +sub allowed { + + my $self = shift; + + if ( ! @_ ) { + return $self->{allowed}; + } else { + return $self->{allowed} = $_[0]; + } + +} + +=head2 add_header + +Adds a header to the headers attribute. Takes two arguments. The first is the name of the header, the second is the header value. + +=cut + +sub add_header { + my ( $self, $key, $value ) =@_; + $self->get_headers->{ $key } = $value; + +} + +1; Property changes on: trunk/ebase/lib/Everything/HTTP/Response/Nodeball.pm ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: trunk/ebase/lib/Everything/HTTP/Response/Test/Nodeball.pm =================================================================== --- trunk/ebase/lib/Everything/HTTP/Response/Test/Nodeball.pm (rev 0) +++ trunk/ebase/lib/Everything/HTTP/Response/Test/Nodeball.pm 2008-07-12 11:56:47 UTC (rev 1011) @@ -0,0 +1,94 @@ +package Everything::HTTP::Response::Test::Nodeball; + +use base 'Everything::Test::Abstract'; +use Test::MockObject; +use Test::More; +use IO::File; +use SUPER; +use strict; +use warnings; + +sub startup : Test(startup => +0) { + + my $self = shift; + my $class = $self->module_class; + + Test::MockObject->fake_module( + 'Apache2::Const', + import => sub { + no strict 'refs'; + *{ $class . '::OK' } = sub { 'ok status code' }; + *{ $class . '::FORBIDDEN' } = sub { 'forbidden status code' }; + use strict 'refs'; + } + ); + + $self->SUPER; + +} + +sub setup :Test(setup) { + my $self = shift; + my $mock = Test::MockObject->new; + $mock->set_always( get_user => $mock ); + $mock->set_always( get_node => $mock ); + $mock->set_true(qw/hasAccess/); + $self->{ mock } = $mock; + $self->{instance} = $self->{class}->new( { request => $mock } ); + +} + +sub test_status_code : Test(2) { + my $self = shift; + my $i = $self->{instance}; + $i->allowed( 1 ); + is ( $i->status_code, 'ok status code', '...returns OK if download allowed.'); + $i->allowed( 0 ); + is ( $i->status_code, 'forbidden status code', '...returns FORBIDDEN if download allowed.'); + +} + +sub test_content : Test(3) { + my $self = shift; + + my $mock = $self->{ mock }; + $mock->set_always( get_request => $mock ); + $mock->set_always( get_nodebase => $mock ); + $mock->set_always( get_node => $mock ); + $mock->set_always( get_title => 'a nodeball title' ); + + my @args = (); + + local *Everything::Storage::Nodeball::export_nodeball_to_file; + *Everything::Storage::Nodeball::export_nodeball_to_file = sub { + push @args, @_; + my $file = $_[2]; + my $fh = IO::File->new( $file, 'w' ); + print $fh "nodeball contents"; + return 1; + }; + + my $i = $self->{ instance }; + $i->allowed( 1 ); + + is( my $rv = $i->content, 'nodeball contents', '... returns contents written to file.' ); + is ( $args[1], 'a nodeball title', '...title of a nodeball.' ); + my %headers = $i->headers; + is_deeply( \%headers, { 'Content-Disposition' => 'attachment; filename=a-nodeball-title.nbz' }, '...sets the Content-Disposition header' ); +} + +sub test_headers :Test(2) { + + my $self = shift; + my $i = $self->{instance}; + my %headers = $i->headers; + is_deeply( \%headers, {}, '...returns an empty list when initialised.' ); + + $i->add_header( Foo => 'Bar' ); + %headers = $i->headers; + is_deeply( \%headers, { Foo => 'Bar' }, '...returns one header when added.' ); + + +} + +1; Property changes on: trunk/ebase/lib/Everything/HTTP/Response/Test/Nodeball.pm ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: trunk/ebase/t/nodeball-responder.t =================================================================== --- trunk/ebase/t/nodeball-responder.t (rev 0) +++ trunk/ebase/t/nodeball-responder.t 2008-07-12 11:56:47 UTC (rev 1011) @@ -0,0 +1,11 @@ +#!/usr/bin/perl -w + +use lib 'blib/lib', 'lib/'; +use Everything::HTTP::Response::Test::Nodeball; + +use strict; + + + + +Everything::HTTP::Response::Test::Nodeball->runtests; Property changes on: trunk/ebase/t/nodeball-responder.t ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pau...@us...> - 2008-07-11 20:26:51
|
Revision: 1010 http://everydevel.svn.sourceforge.net/everydevel/?rev=1010&view=rev Author: paul_the_nomad Date: 2008-07-11 13:26:45 -0700 (Fri, 11 Jul 2008) Log Message: ----------- Changes to ResponseFactory and Apache.pm to allow more flexible responses. Inclusion of a Nodeball response type to allow direct downloads of nodeballs. Modified Paths: -------------- trunk/ebase/TODO trunk/ebase/lib/Everything/Config.pm trunk/ebase/lib/Everything/HTTP/Apache.pm trunk/ebase/lib/Everything/HTTP/Response/Htmlpage.pm trunk/ebase/lib/Everything/HTTP/Response/Test/Htmlpage.pm trunk/ebase/lib/Everything/HTTP/ResponseFactory.pm trunk/ebase/lib/Everything/HTTP/Test/Apache.pm trunk/ebase/t/lib/everything.conf Modified: trunk/ebase/TODO =================================================================== --- trunk/ebase/TODO 2008-07-11 20:20:42 UTC (rev 1009) +++ trunk/ebase/TODO 2008-07-11 20:26:45 UTC (rev 1010) @@ -5,6 +5,9 @@ * Amend ecore to ensure XHTML 1.0 compliance +* Amend FromObject.pm so that form objects return labels with a 'for' + attribute and id in the input tag. + * Require Everything::HTML::Response classes to create certain HTTP headers * Everything::HTML::Response classes to return error values on error - Modified: trunk/ebase/lib/Everything/Config.pm =================================================================== --- trunk/ebase/lib/Everything/Config.pm 2008-07-11 20:20:42 UTC (rev 1009) +++ trunk/ebase/lib/Everything/Config.pm 2008-07-11 20:26:45 UTC (rev 1010) @@ -202,11 +202,22 @@ javascript => sub { my ( $url, $e ) = @_; return unless $url =~ /\/javascript\/([0-9]+)\.js$/; - my $js_node = $e->get_nodebase->get_node($1); + my $js_node = $e->get_nodebase->getNode($1); $e->set_response_type('javascript'); $e->set_node($js_node); 1; }, + + nodeball_download => sub { + my ( $url, $e ) = @_; + return unless $url =~ m{^/repositories/nodeballs/(\d+)}; + my $node = $e->get_nodebase->getNode( $1 ); + return unless ref $node; + return unless $node->isa( 'Everything::Node::nodeball' ); + $e->set_node( $node ); + $e->set_response_type( 'nodeball' ); + return 1; + } ); sub get_standard_modifier { $standard_modifiers{ $_[1] } } Modified: trunk/ebase/lib/Everything/HTTP/Apache.pm =================================================================== --- trunk/ebase/lib/Everything/HTTP/Apache.pm 2008-07-11 20:20:42 UTC (rev 1009) +++ trunk/ebase/lib/Everything/HTTP/Apache.pm 2008-07-11 20:26:45 UTC (rev 1010) @@ -72,21 +72,34 @@ ### XXX- set in config file response factory ### XXX- response factory should set up the environment that htmlpage needs - my $response = Everything::HTTP::ResponseFactory->new( $e->get_response_type || 'htmlpage', $e ); - $response->create_http_body( { config => $config } ); - my $html = $response->get_http_body; + my $response = Everything::HTTP::ResponseFactory->new( $e->get_response_type || 'htmlpage', { config => $config, request => $e } ); + ### new actually creates the response - so get rid of 'create http body' + ### check response code + ### check headers + ### check content + ### return status_code + + my $html = $response->content(); + $r->content_type( $response->content_type ); $r->headers_out->set( 'Set-Cookie' => $e->get_user->{cookie} ); + my %headers = $response->headers; + + foreach ( keys %headers ) { + $r->headers_out->set( $_ => $headers{ $_ } ); + } + $r->print($html); - # To ensure any changes in VARS are saved to the db + # XXX: These should be set in the Response object + # NB: These lines ensure any changes in VARS are saved to the db $e->get_user->setVars( $e->get_user_vars, $e->get_user ); $e->get_user->update( $e->get_user ); - return OK; + return $response->status_code; } Modified: trunk/ebase/lib/Everything/HTTP/Response/Htmlpage.pm =================================================================== --- trunk/ebase/lib/Everything/HTTP/Response/Htmlpage.pm 2008-07-11 20:20:42 UTC (rev 1009) +++ trunk/ebase/lib/Everything/HTTP/Response/Htmlpage.pm 2008-07-11 20:26:45 UTC (rev 1010) @@ -6,7 +6,7 @@ use base 'Class::Accessor::Fast'; __PACKAGE__->follow_best_practice; __PACKAGE__->mk_accessors( - qw/http_header http_body request htmlpage theme allowed redirect/); + qw/http_header http_body request htmlpage theme allowed redirect config/); use strict; ### because this is called from a Class::Factory object new is not @@ -19,18 +19,19 @@ } sub init { - my ( $self, $e ) = @_; - $self->set_request($e); + my ( $self, $args ) = @_; + $self->set_request( $args->{request} ); + $self->set_config( $args->{config} ); $self->select_htmlpage; return $self; } -sub create_http_body { +sub content { my ( $self, $args ) = @_; my $htmlpage = $self->get_htmlpage; - my $config = $$args{ config }; + my $config = $self->get_config; my $ehtml = Everything::HTML->new; if ( $config ) { @@ -58,7 +59,31 @@ } +=head2 headers + +The headers other than Content-Type + +=cut + +sub headers { + + (); + +} + +=head2 status_code + +Returns the HTTP status code of the response. This is always 'OK', because HTMLPAGES always accept a request. + +=cut + +sub status_code { + + 0; ## Apache prefers this to 200. +} + sub charset { + 'utf-8' } Modified: trunk/ebase/lib/Everything/HTTP/Response/Test/Htmlpage.pm =================================================================== --- trunk/ebase/lib/Everything/HTTP/Response/Test/Htmlpage.pm 2008-07-11 20:20:42 UTC (rev 1009) +++ trunk/ebase/lib/Everything/HTTP/Response/Test/Htmlpage.pm 2008-07-11 20:26:45 UTC (rev 1010) @@ -34,7 +34,7 @@ $mock->set_always( 'getType', $mock ); $mock->{title} = 'a title'; $self->{mock} = $mock; - isa_ok( $self->{instance} = $self->{class}->new($mock), $self->{class} ); + isa_ok( $self->{instance} = $self->{class}->new( { request => $mock } ), $self->{class} ); } @@ -42,7 +42,7 @@ my $self = shift; my $class = $self->{class}; my $instance = $self->{instance}; - can_ok( $class, 'create_http_body' ); + can_ok( $class, 'content' ); can_ok( $class, 'content_type' ); } Modified: trunk/ebase/lib/Everything/HTTP/ResponseFactory.pm =================================================================== --- trunk/ebase/lib/Everything/HTTP/ResponseFactory.pm 2008-07-11 20:20:42 UTC (rev 1009) +++ trunk/ebase/lib/Everything/HTTP/ResponseFactory.pm 2008-07-11 20:26:45 UTC (rev 1010) @@ -7,6 +7,7 @@ __PACKAGE__->add_factory_type('htmlpage' => 'Everything::HTTP::Response::Htmlpage'); +__PACKAGE__->add_factory_type('nodeball' => 'Everything::HTTP::Response::Nodeball'); =head1 Everything::HTTP::ResponseFactory @@ -18,58 +19,75 @@ Everything::HTTP::ResponseFactory->add_factory_type('anothertype' => 'Name::of::another::package'); -my $response = Everything::HTTP::ResponseFactory->new(<response type>, [@args]); +my $response = Everything::HTTP::ResponseFactory->new(<response type>, { args } ); -$response->create_http_body; +my $html = $response->content; -my $html = $response->get_http_body; +my $content_type = $response->content_type; -my $mime_type = $response->get_mime_type; -my $header = $response->create_http_header; - - =head1 DESCRIPTION This is a factory class, that is, the constructor returns instances that are blessed into other classes, not this one. This class inherits from C<Class::Factory>, so the rules for adding types and the rules instanciation are the same as they are in C<Class::Factory>. In essense, if you want to customise the way your classes are instanciated you should use the C<init> method. -In addition, the instances that this class provides must support the following methods: +The objects created by this class must return values that allow a +response be sent back to the client browser. =over 4 -=item get_http_body set_http_body +=item C<new> -Getters and setters for the http_body attribute. +This is the constructor. It takes two arguments: -=item get_http_header set_http_header +=over -Getters and setters for the http_header attribute. +=item -=item get_mime_type set_mime_type +The first is a string that determines the type of object return. -Getters and setters for the mime_type attribute. +=item +The second is a hash ref that is passed straight to the created objects. Attributes may include: + +=over + +=item config + +An Everything::Config object. + +=item request + +An Everything::HTTP::Request object. + =back -In addition, the followimg methods must be supported: +=back +=back + +In addition, the instances that this class provides must support the following methods: + =over 4 -=item create_http_header +=item content_type -Conjures a conforming http header and sets the http_header attribute. +Returns the data for the Content-Type header. -=item create_http_body +=item headers -Conjures up a conforming http body and sets the http_body attribute. +Returns a hash of headers. By default does not return the Content-Type header. -=item create_mime_type +=item content -Conjures up a mime type (from where is not important) and sets the mime_type attribute. +Returns the message body +=item status_code + +Returns the HTTP status code. + =back =cut Modified: trunk/ebase/lib/Everything/HTTP/Test/Apache.pm =================================================================== --- trunk/ebase/lib/Everything/HTTP/Test/Apache.pm 2008-07-11 20:20:42 UTC (rev 1009) +++ trunk/ebase/lib/Everything/HTTP/Test/Apache.pm 2008-07-11 20:26:45 UTC (rev 1010) @@ -21,10 +21,11 @@ $mock->fake_module('Everything::HTTP::ResponseFactory'); $mock->fake_new('Everything::HTTP::ResponseFactory'); - $mock->set_true(qw/create_http_body/) + $mock->set_true(qw/content/) ->set_always( content_type => 'a mime type' ) - ->set_always( 'get_http_body', 'the html body' ); + ->set_always( 'content', 'the html body' ); + $mock->set_always( status_code => 0 ); $self->{class} = $self->module_class; use_ok( $self->{class} ); @@ -42,7 +43,7 @@ return $name; } -sub test_handler : Test(23) { +sub test_handler : Test(22) { my $self = shift; my $mock = $self->{mock}; my $fake_everything_request = $self->{fake_everything_request}; @@ -128,18 +129,15 @@ ( $method, $args ) = $fake_apache_request->next_call; is( $method, 'print', - '...currently do our own cookies until Auth.pm rewrite.' ); + '...prints response.' ); is( $args->[1], 'the html body', '...prints http header.' ); is( $result, 0, '...should return correct result' ); ( $method, $args ) = $mock->next_call; - is( $method, 'create_http_body', '...factory creates http body.' ); + is( $method, 'content', '...factory creates http body.' ); ( $method, $args ) = $mock->next_call; - is( $method, 'get_http_body', '...retrieves http body.' ); - - ( $method, $args ) = $mock->next_call; is( $method, 'content_type', '...returns mime type.' ); ( $method, $args ) = $mock->next_call; Modified: trunk/ebase/t/lib/everything.conf =================================================================== --- trunk/ebase/t/lib/everything.conf 2008-07-11 20:20:42 UTC (rev 1009) +++ trunk/ebase/t/lib/everything.conf 2008-07-11 20:26:45 UTC (rev 1010) @@ -2,6 +2,8 @@ database_type = sqlite location_schema_nodetype = /node/:node_id node +request_modifier_standard = nodeball_download + request_modifier_code = <<"FOOFOO" sub { my ($url, $e ) = @_; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |