Schema and model changes to support invitations and multiple user collaboration:
* added new database table of invited email addresses * altered user_notebook table to have a new owner boolean column, indicating whether the user has owner access to the notebook * altered notebook and note tables/views to have an additional user_id field to indicate the user that created that revision * updated model.Notebook and model.Note to support new user_id field
This commit is contained in:
parent
ac3759dcee
commit
82bf5bca29
|
@ -10,7 +10,7 @@ class Note( Persistent ):
|
||||||
TITLE_PATTERN = re.compile( u"<h3>(.*?)</h3>", flags = re.IGNORECASE )
|
TITLE_PATTERN = re.compile( u"<h3>(.*?)</h3>", flags = re.IGNORECASE )
|
||||||
|
|
||||||
def __init__( self, object_id, revision = None, title = None, contents = None, notebook_id = None,
|
def __init__( self, object_id, revision = None, title = None, contents = None, notebook_id = None,
|
||||||
startup = None, deleted_from_id = None, rank = None, creation = None, summary = None ):
|
startup = None, deleted_from_id = None, rank = None, user_id = None, creation = None, summary = None ):
|
||||||
"""
|
"""
|
||||||
Create a new note with the given id and contents.
|
Create a new note with the given id and contents.
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@ class Note( Persistent ):
|
||||||
@param deleted_from_id: id of the notebook that this note was deleted from (optional)
|
@param deleted_from_id: id of the notebook that this note was deleted from (optional)
|
||||||
@type rank: float or NoneType
|
@type rank: float or NoneType
|
||||||
@param rank: indicates numeric ordering of this note in relation to other startup notes
|
@param rank: indicates numeric ordering of this note in relation to other startup notes
|
||||||
|
@type user_id: unicode or NoneType
|
||||||
|
@param user_id: id of the user who most recently updated this note object (optional)
|
||||||
@type creation: datetime or NoneType
|
@type creation: datetime or NoneType
|
||||||
@param creation: creation timestamp of the object (optional, defaults to None)
|
@param creation: creation timestamp of the object (optional, defaults to None)
|
||||||
@type summary: unicode or NoneType
|
@type summary: unicode or NoneType
|
||||||
|
@ -45,10 +47,11 @@ class Note( Persistent ):
|
||||||
self.__startup = startup or False
|
self.__startup = startup or False
|
||||||
self.__deleted_from_id = deleted_from_id
|
self.__deleted_from_id = deleted_from_id
|
||||||
self.__rank = rank
|
self.__rank = rank
|
||||||
|
self.__user_id = user_id
|
||||||
self.__creation = creation
|
self.__creation = creation
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create( object_id, contents = None, notebook_id = None, startup = None, rank = None, creation = None, summary = None ):
|
def create( object_id, contents = None, notebook_id = None, startup = None, rank = None, user_id = None, creation = None, summary = None ):
|
||||||
"""
|
"""
|
||||||
Convenience constructor for creating a new note.
|
Convenience constructor for creating a new note.
|
||||||
|
|
||||||
|
@ -62,6 +65,8 @@ class Note( Persistent ):
|
||||||
@param startup: whether this note should be displayed upon startup (optional, defaults to False)
|
@param startup: whether this note should be displayed upon startup (optional, defaults to False)
|
||||||
@type rank: float or NoneType
|
@type rank: float or NoneType
|
||||||
@param rank: indicates numeric ordering of this note in relation to other startup notes
|
@param rank: indicates numeric ordering of this note in relation to other startup notes
|
||||||
|
@type user_id: unicode or NoneType
|
||||||
|
@param user_id: id of the user who most recently updated this note object (optional)
|
||||||
@type creation: datetime or NoneType
|
@type creation: datetime or NoneType
|
||||||
@param creation: creation timestamp of the object (optional, defaults to None)
|
@param creation: creation timestamp of the object (optional, defaults to None)
|
||||||
@type summary: unicode or NoneType
|
@type summary: unicode or NoneType
|
||||||
|
@ -69,7 +74,7 @@ class Note( Persistent ):
|
||||||
@rtype: Note
|
@rtype: Note
|
||||||
@return: newly constructed note
|
@return: newly constructed note
|
||||||
"""
|
"""
|
||||||
note = Note( object_id, notebook_id = notebook_id, startup = startup, rank = rank, creation = creation, summary = summary )
|
note = Note( object_id, notebook_id = notebook_id, startup = startup, rank = rank, user_id = user_id, creation = creation, summary = summary )
|
||||||
note.contents = contents
|
note.contents = contents
|
||||||
|
|
||||||
return note
|
return note
|
||||||
|
@ -113,9 +118,9 @@ class Note( Persistent ):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def sql_load( object_id, revision = None ):
|
def sql_load( object_id, revision = None ):
|
||||||
if revision:
|
if revision:
|
||||||
return "select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank from note where id = %s and revision = %s;" % ( quote( object_id ), quote( revision ) )
|
return "select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank, user_id from note where id = %s and revision = %s;" % ( quote( object_id ), quote( revision ) )
|
||||||
|
|
||||||
return "select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank from note_current where id = %s;" % quote( object_id )
|
return "select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank, user_id from note_current where id = %s;" % quote( object_id )
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def sql_id_exists( object_id, revision = None ):
|
def sql_id_exists( object_id, revision = None ):
|
||||||
|
@ -133,11 +138,11 @@ class Note( Persistent ):
|
||||||
rank = quote( None )
|
rank = quote( None )
|
||||||
|
|
||||||
return \
|
return \
|
||||||
"insert into note ( id, revision, title, contents, notebook_id, startup, deleted_from_id, rank ) " + \
|
"insert into note ( id, revision, title, contents, notebook_id, startup, deleted_from_id, rank, user_id ) " + \
|
||||||
"values ( %s, %s, %s, %s, %s, %s, %s, %s );" % \
|
"values ( %s, %s, %s, %s, %s, %s, %s, %s, %s );" % \
|
||||||
( quote( self.object_id ), quote( self.revision ), quote( self.__title ),
|
( quote( self.object_id ), quote( self.revision ), quote( self.__title ),
|
||||||
quote( self.__contents ), quote( self.__notebook_id ), quote( self.__startup and 't' or 'f' ),
|
quote( self.__contents ), quote( self.__notebook_id ), quote( self.__startup and 't' or 'f' ),
|
||||||
quote( self.__deleted_from_id ), rank )
|
quote( self.__deleted_from_id ), rank, quote( self.user_id ) )
|
||||||
|
|
||||||
def sql_update( self ):
|
def sql_update( self ):
|
||||||
return self.sql_create()
|
return self.sql_create()
|
||||||
|
@ -152,6 +157,7 @@ class Note( Persistent ):
|
||||||
summary = self.__summary,
|
summary = self.__summary,
|
||||||
title = self.__title,
|
title = self.__title,
|
||||||
deleted_from_id = self.__deleted_from_id,
|
deleted_from_id = self.__deleted_from_id,
|
||||||
|
user_id = self.__user_id,
|
||||||
creation = self.__creation,
|
creation = self.__creation,
|
||||||
) )
|
) )
|
||||||
|
|
||||||
|
@ -164,4 +170,5 @@ class Note( Persistent ):
|
||||||
startup = property( lambda self: self.__startup, __set_startup )
|
startup = property( lambda self: self.__startup, __set_startup )
|
||||||
deleted_from_id = property( lambda self: self.__deleted_from_id, __set_deleted_from_id )
|
deleted_from_id = property( lambda self: self.__deleted_from_id, __set_deleted_from_id )
|
||||||
rank = property( lambda self: self.__rank, __set_rank )
|
rank = property( lambda self: self.__rank, __set_rank )
|
||||||
|
user_id = property( lambda self: self.__user_id )
|
||||||
creation = property( lambda self: self.__creation )
|
creation = property( lambda self: self.__creation )
|
||||||
|
|
|
@ -12,7 +12,7 @@ class Notebook( Persistent ):
|
||||||
WHITESPACE_PATTERN = re.compile( r"\s+" )
|
WHITESPACE_PATTERN = re.compile( r"\s+" )
|
||||||
SEARCH_OPERATORS = re.compile( r"[&|!()]" )
|
SEARCH_OPERATORS = re.compile( r"[&|!()]" )
|
||||||
|
|
||||||
def __init__( self, object_id, revision = None, name = None, trash_id = None, deleted = False, read_write = True ):
|
def __init__( self, object_id, revision = None, name = None, trash_id = None, deleted = False, user_id = None, read_write = True ):
|
||||||
"""
|
"""
|
||||||
Create a new notebook with the given id and name.
|
Create a new notebook with the given id and name.
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ class Notebook( Persistent ):
|
||||||
@param trash_id: id of the notebook where deleted notes from this notebook go to die (optional)
|
@param trash_id: id of the notebook where deleted notes from this notebook go to die (optional)
|
||||||
@type deleted: bool or NoneType
|
@type deleted: bool or NoneType
|
||||||
@param deleted: whether this notebook is currently deleted (optional, defaults to False)
|
@param deleted: whether this notebook is currently deleted (optional, defaults to False)
|
||||||
|
@type user_id: unicode or NoneType
|
||||||
|
@param user_id: id of the user who most recently updated this notebook object (optional)
|
||||||
@type read_write: bool or NoneType
|
@type read_write: bool or NoneType
|
||||||
@param read_write: whether this view of the notebook is currently read-write (optional, defaults to True)
|
@param read_write: whether this view of the notebook is currently read-write (optional, defaults to True)
|
||||||
@rtype: Notebook
|
@rtype: Notebook
|
||||||
|
@ -35,10 +37,11 @@ class Notebook( Persistent ):
|
||||||
self.__name = name
|
self.__name = name
|
||||||
self.__trash_id = trash_id
|
self.__trash_id = trash_id
|
||||||
self.__deleted = deleted
|
self.__deleted = deleted
|
||||||
|
self.__user_id = user_id
|
||||||
self.__read_write = read_write
|
self.__read_write = read_write
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create( object_id, name = None, trash_id = None, deleted = False, read_write = True ):
|
def create( object_id, name = None, trash_id = None, deleted = False, user_id = None, read_write = True ):
|
||||||
"""
|
"""
|
||||||
Convenience constructor for creating a new notebook.
|
Convenience constructor for creating a new notebook.
|
||||||
|
|
||||||
|
@ -50,12 +53,14 @@ class Notebook( Persistent ):
|
||||||
@param trash_id: id of the notebook where deleted notes from this notebook go to die (optional)
|
@param trash_id: id of the notebook where deleted notes from this notebook go to die (optional)
|
||||||
@type deleted: bool or NoneType
|
@type deleted: bool or NoneType
|
||||||
@param deleted: whether this notebook is currently deleted (optional, defaults to False)
|
@param deleted: whether this notebook is currently deleted (optional, defaults to False)
|
||||||
|
@type user_id: unicode or NoneType
|
||||||
|
@param user_id: id of the user who most recently updated this notebook object (optional)
|
||||||
@type read_write: bool or NoneType
|
@type read_write: bool or NoneType
|
||||||
@param read_write: whether this view of the notebook is currently read-write (optional, defaults to True)
|
@param read_write: whether this view of the notebook is currently read-write (optional, defaults to True)
|
||||||
@rtype: Notebook
|
@rtype: Notebook
|
||||||
@return: newly constructed notebook
|
@return: newly constructed notebook
|
||||||
"""
|
"""
|
||||||
return Notebook( object_id, name = name, trash_id = trash_id, read_write = read_write )
|
return Notebook( object_id, name = name, trash_id = trash_id, user_id = user_id, read_write = read_write )
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def sql_load( object_id, revision = None ):
|
def sql_load( object_id, revision = None ):
|
||||||
|
@ -76,10 +81,10 @@ class Notebook( Persistent ):
|
||||||
|
|
||||||
def sql_create( self ):
|
def sql_create( self ):
|
||||||
return \
|
return \
|
||||||
"insert into notebook ( id, revision, name, trash_id, deleted ) " + \
|
"insert into notebook ( id, revision, name, trash_id, deleted, user_id ) " + \
|
||||||
"values ( %s, %s, %s, %s, %s );" % \
|
"values ( %s, %s, %s, %s, %s, %s );" % \
|
||||||
( quote( self.object_id ), quote( self.revision ), quote( self.__name ),
|
( quote( self.object_id ), quote( self.revision ), quote( self.__name ),
|
||||||
quote( self.__trash_id ), quote( self.deleted ) )
|
quote( self.__trash_id ), quote( self.deleted ), quote( self.user_id ) )
|
||||||
|
|
||||||
def sql_update( self ):
|
def sql_update( self ):
|
||||||
return self.sql_create()
|
return self.sql_create()
|
||||||
|
@ -88,19 +93,19 @@ class Notebook( Persistent ):
|
||||||
"""
|
"""
|
||||||
Return a SQL string to load a list of all the notes within this notebook.
|
Return a SQL string to load a list of all the notes within this notebook.
|
||||||
"""
|
"""
|
||||||
return "select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank from note_current where notebook_id = %s order by revision desc;" % quote( self.object_id )
|
return "select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank, user_id from note_current where notebook_id = %s order by revision desc;" % quote( self.object_id )
|
||||||
|
|
||||||
def sql_load_non_startup_notes( self ):
|
def sql_load_non_startup_notes( self ):
|
||||||
"""
|
"""
|
||||||
Return a SQL string to load a list of the non-startup notes within this notebook.
|
Return a SQL string to load a list of the non-startup notes within this notebook.
|
||||||
"""
|
"""
|
||||||
return "select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank from note_current where notebook_id = %s and startup = 'f' order by revision desc;" % quote( self.object_id )
|
return "select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank, user_id from note_current where notebook_id = %s and startup = 'f' order by revision desc;" % quote( self.object_id )
|
||||||
|
|
||||||
def sql_load_startup_notes( self ):
|
def sql_load_startup_notes( self ):
|
||||||
"""
|
"""
|
||||||
Return a SQL string to load a list of the startup notes within this notebook.
|
Return a SQL string to load a list of the startup notes within this notebook.
|
||||||
"""
|
"""
|
||||||
return "select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank from note_current where notebook_id = %s and startup = 't' order by rank;" % quote( self.object_id )
|
return "select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank, user_id from note_current where notebook_id = %s and startup = 't' order by rank;" % quote( self.object_id )
|
||||||
|
|
||||||
def sql_load_recent_notes( self, start = 0, count = 10 ):
|
def sql_load_recent_notes( self, start = 0, count = 10 ):
|
||||||
"""
|
"""
|
||||||
|
@ -116,7 +121,7 @@ class Notebook( Persistent ):
|
||||||
select
|
select
|
||||||
note_current.id, note_current.revision, note_current.title, note_current.contents,
|
note_current.id, note_current.revision, note_current.title, note_current.contents,
|
||||||
note_current.notebook_id, note_current.startup, note_current.deleted_from_id,
|
note_current.notebook_id, note_current.startup, note_current.deleted_from_id,
|
||||||
note_current.rank, note_creation.revision as creation
|
note_current.rank, note_current.user_id, note_creation.revision as creation
|
||||||
from
|
from
|
||||||
note_current,
|
note_current,
|
||||||
( select id, min( revision ) as revision from note where notebook_id = %s group by id ) as note_creation
|
( select id, min( revision ) as revision from note where notebook_id = %s group by id ) as note_creation
|
||||||
|
@ -134,7 +139,7 @@ class Notebook( Persistent ):
|
||||||
@type note_id: unicode
|
@type note_id: unicode
|
||||||
@param note_id: id of note to load
|
@param note_id: id of note to load
|
||||||
"""
|
"""
|
||||||
return "select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank from note_current where notebook_id = %s and id = %s;" % ( quote( self.object_id ), quote( note_id ) )
|
return "select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank, user_id from note_current where notebook_id = %s and id = %s;" % ( quote( self.object_id ), quote( note_id ) )
|
||||||
|
|
||||||
def sql_load_note_by_title( self, title ):
|
def sql_load_note_by_title( self, title ):
|
||||||
"""
|
"""
|
||||||
|
@ -143,7 +148,7 @@ class Notebook( Persistent ):
|
||||||
@type note_id: unicode
|
@type note_id: unicode
|
||||||
@param note_id: title of note to load
|
@param note_id: title of note to load
|
||||||
"""
|
"""
|
||||||
return "select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank from note_current where notebook_id = %s and title = %s;" % ( quote( self.object_id ), quote( title ) )
|
return "select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank, user_id from note_current where notebook_id = %s and title = %s;" % ( quote( self.object_id ), quote( title ) )
|
||||||
|
|
||||||
def sql_search_notes( self, search_text ):
|
def sql_search_notes( self, search_text ):
|
||||||
"""
|
"""
|
||||||
|
@ -161,10 +166,10 @@ class Notebook( Persistent ):
|
||||||
|
|
||||||
return \
|
return \
|
||||||
"""
|
"""
|
||||||
select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank, null,
|
select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank, user_id, null,
|
||||||
headline( drop_html_tags( contents ), query ) as summary from (
|
headline( drop_html_tags( contents ), query ) as summary from (
|
||||||
select
|
select
|
||||||
id, revision, title, contents, notebook_id, startup, deleted_from_id, rank_cd( search, query ) as rank, null, query
|
id, revision, title, contents, notebook_id, startup, deleted_from_id, rank_cd( search, query ) as rank, user_id, null, query
|
||||||
from
|
from
|
||||||
note_current, to_tsquery( 'default', %s ) query
|
note_current, to_tsquery( 'default', %s ) query
|
||||||
where
|
where
|
||||||
|
@ -194,6 +199,7 @@ class Notebook( Persistent ):
|
||||||
trash_id = self.__trash_id,
|
trash_id = self.__trash_id,
|
||||||
read_write = self.__read_write,
|
read_write = self.__read_write,
|
||||||
deleted = self.__deleted,
|
deleted = self.__deleted,
|
||||||
|
user_id = self.__user_id,
|
||||||
) )
|
) )
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
@ -215,3 +221,4 @@ class Notebook( Persistent ):
|
||||||
trash_id = property( lambda self: self.__trash_id )
|
trash_id = property( lambda self: self.__trash_id )
|
||||||
read_write = property( lambda self: self.__read_write, __set_read_write )
|
read_write = property( lambda self: self.__read_write, __set_read_write )
|
||||||
deleted = property( lambda self: self.__deleted, __set_deleted )
|
deleted = property( lambda self: self.__deleted, __set_deleted )
|
||||||
|
user_id = property( lambda self: self.__user_id )
|
||||||
|
|
|
@ -145,7 +145,7 @@ class User( Persistent ):
|
||||||
|
|
||||||
return \
|
return \
|
||||||
"select notebook_current.*, user_notebook.read_write from user_notebook, notebook_current " + \
|
"select notebook_current.*, user_notebook.read_write from user_notebook, notebook_current " + \
|
||||||
"where user_id = %s%s%s and user_notebook.notebook_id = notebook_current.id order by revision;" % \
|
"where user_notebook.user_id = %s%s%s and user_notebook.notebook_id = notebook_current.id order by revision;" % \
|
||||||
( quote( self.object_id ), parents_only_clause, undeleted_only_clause )
|
( quote( self.object_id ), parents_only_clause, undeleted_only_clause )
|
||||||
|
|
||||||
def sql_save_notebook( self, notebook_id, read_write = True ):
|
def sql_save_notebook( self, notebook_id, read_write = True ):
|
||||||
|
|
23
model/delta/1.0.4.sql
Normal file
23
model/delta/1.0.4.sql
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
create table invite (
|
||||||
|
id text not null,
|
||||||
|
revision timestamp with time zone not null,
|
||||||
|
sent_user_id text,
|
||||||
|
notebook_id text,
|
||||||
|
email_address text,
|
||||||
|
read_write boolean,
|
||||||
|
owner boolean,
|
||||||
|
redeemed_user_id text
|
||||||
|
);
|
||||||
|
alter table invite add primary key ( id );
|
||||||
|
alter table user_notebook add column owner boolean default false;
|
||||||
|
update user_notebook set owner = 't' where read_write = 't';
|
||||||
|
alter table notebook add column user_id text;
|
||||||
|
alter table note add column user_id text;
|
||||||
|
drop view notebook_current;
|
||||||
|
create view notebook_current as SELECT id, revision, name, trash_id, deleted, user_id
|
||||||
|
from notebook
|
||||||
|
where ( notebook.revision IN ( SELECT max( sub_notebook.revision ) AS max FROM notebook sub_notebook
|
||||||
|
where sub_notebook.id = notebook.id ) );
|
||||||
|
drop view note_current;
|
||||||
|
create view note_current as select id, revision, title, contents, notebook_id, startup, deleted_from_id, rank, search, user_id
|
||||||
|
from note where ( note.revision in ( select max( sub_note.revision ) as max from note sub_note where sub_note.id = note.id ) );
|
|
@ -31,6 +31,24 @@ CREATE FUNCTION drop_html_tags(text) RETURNS text
|
||||||
|
|
||||||
ALTER FUNCTION public.drop_html_tags(text) OWNER TO luminotes;
|
ALTER FUNCTION public.drop_html_tags(text) OWNER TO luminotes;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: invite; Type: TABLE; Schema: public; Owner: luminotes; Tablespace:
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE invite (
|
||||||
|
id text NOT NULL,
|
||||||
|
revision timestamp with time zone NOT NULL,
|
||||||
|
sent_user_id text,
|
||||||
|
notebook_id text,
|
||||||
|
email_address text,
|
||||||
|
read_write boolean,
|
||||||
|
"owner" boolean,
|
||||||
|
redeemed_user_id text
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE public.invite OWNER TO luminotes;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: luminotes_user; Type: TABLE; Schema: public; Owner: luminotes; Tablespace:
|
-- Name: luminotes_user; Type: TABLE; Schema: public; Owner: luminotes; Tablespace:
|
||||||
--
|
--
|
||||||
|
@ -72,7 +90,8 @@ CREATE TABLE note (
|
||||||
startup boolean DEFAULT false,
|
startup boolean DEFAULT false,
|
||||||
deleted_from_id text,
|
deleted_from_id text,
|
||||||
rank numeric,
|
rank numeric,
|
||||||
search tsvector
|
search tsvector,
|
||||||
|
user_id text
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,7 +102,7 @@ ALTER TABLE public.note OWNER TO luminotes;
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE VIEW note_current AS
|
CREATE VIEW note_current AS
|
||||||
SELECT note.id, note.revision, note.title, note.contents, note.notebook_id, note.startup, note.deleted_from_id, note.rank, note.search FROM note WHERE (note.revision IN (SELECT max(sub_note.revision) AS max FROM note sub_note WHERE (sub_note.id = note.id)));
|
SELECT note.id, note.revision, note.title, note.contents, note.notebook_id, note.startup, note.deleted_from_id, note.rank, note.search, note.user_id FROM note WHERE (note.revision IN (SELECT max(sub_note.revision) AS max FROM note sub_note WHERE (sub_note.id = note.id)));
|
||||||
|
|
||||||
|
|
||||||
ALTER TABLE public.note_current OWNER TO luminotes;
|
ALTER TABLE public.note_current OWNER TO luminotes;
|
||||||
|
@ -97,7 +116,8 @@ CREATE TABLE notebook (
|
||||||
revision timestamp with time zone NOT NULL,
|
revision timestamp with time zone NOT NULL,
|
||||||
name text,
|
name text,
|
||||||
trash_id text,
|
trash_id text,
|
||||||
deleted boolean DEFAULT false
|
deleted boolean DEFAULT false,
|
||||||
|
user_id text
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -108,7 +128,7 @@ ALTER TABLE public.notebook OWNER TO luminotes;
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE VIEW notebook_current AS
|
CREATE VIEW notebook_current AS
|
||||||
SELECT notebook.id, notebook.revision, notebook.name, notebook.trash_id, notebook.deleted FROM notebook WHERE (notebook.revision IN (SELECT max(sub_notebook.revision) AS max FROM notebook sub_notebook WHERE (sub_notebook.id = notebook.id)));
|
SELECT notebook.id, notebook.revision, notebook.name, notebook.trash_id, notebook.deleted, notebook.user_id FROM notebook WHERE (notebook.revision IN (SELECT max(sub_notebook.revision) AS max FROM notebook sub_notebook WHERE (sub_notebook.id = notebook.id)));
|
||||||
|
|
||||||
|
|
||||||
ALTER TABLE public.notebook_current OWNER TO luminotes;
|
ALTER TABLE public.notebook_current OWNER TO luminotes;
|
||||||
|
@ -134,12 +154,21 @@ ALTER TABLE public.password_reset OWNER TO luminotes;
|
||||||
CREATE TABLE user_notebook (
|
CREATE TABLE user_notebook (
|
||||||
user_id text NOT NULL,
|
user_id text NOT NULL,
|
||||||
notebook_id text NOT NULL,
|
notebook_id text NOT NULL,
|
||||||
read_write boolean DEFAULT false
|
read_write boolean DEFAULT false,
|
||||||
|
"owner" boolean DEFAULT false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
ALTER TABLE public.user_notebook OWNER TO luminotes;
|
ALTER TABLE public.user_notebook OWNER TO luminotes;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: invite_pkey; Type: CONSTRAINT; Schema: public; Owner: luminotes; Tablespace:
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY invite
|
||||||
|
ADD CONSTRAINT invite_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: luminotes_user_pkey; Type: CONSTRAINT; Schema: public; Owner: luminotes; Tablespace:
|
-- Name: luminotes_user_pkey; Type: CONSTRAINT; Schema: public; Owner: luminotes; Tablespace:
|
||||||
--
|
--
|
||||||
|
|
|
@ -12,10 +12,11 @@ class Test_note( object ):
|
||||||
self.notebook_id = u"18"
|
self.notebook_id = u"18"
|
||||||
self.startup = False
|
self.startup = False
|
||||||
self.rank = 17.5
|
self.rank = 17.5
|
||||||
|
self.user_id = u"me"
|
||||||
self.creation = datetime.now()
|
self.creation = datetime.now()
|
||||||
self.delta = timedelta( seconds = 1 )
|
self.delta = timedelta( seconds = 1 )
|
||||||
|
|
||||||
self.note = Note.create( self.object_id, self.contents, self.notebook_id, self.startup, self.rank, self.creation, self.summary )
|
self.note = Note.create( self.object_id, self.contents, self.notebook_id, self.startup, self.rank, self.user_id, self.creation, self.summary )
|
||||||
|
|
||||||
def test_create( self ):
|
def test_create( self ):
|
||||||
assert self.note.object_id == self.object_id
|
assert self.note.object_id == self.object_id
|
||||||
|
@ -27,6 +28,7 @@ class Test_note( object ):
|
||||||
assert self.note.startup == self.startup
|
assert self.note.startup == self.startup
|
||||||
assert self.note.deleted_from_id == None
|
assert self.note.deleted_from_id == None
|
||||||
assert self.note.rank == self.rank
|
assert self.note.rank == self.rank
|
||||||
|
assert self.note.user_id == self.user_id
|
||||||
assert self.note.creation == self.creation
|
assert self.note.creation == self.creation
|
||||||
|
|
||||||
def test_set_contents( self ):
|
def test_set_contents( self ):
|
||||||
|
@ -44,6 +46,7 @@ class Test_note( object ):
|
||||||
assert self.note.startup == self.startup
|
assert self.note.startup == self.startup
|
||||||
assert self.note.deleted_from_id == None
|
assert self.note.deleted_from_id == None
|
||||||
assert self.note.rank == self.rank
|
assert self.note.rank == self.rank
|
||||||
|
assert self.note.user_id == self.user_id
|
||||||
assert self.note.creation == self.creation
|
assert self.note.creation == self.creation
|
||||||
|
|
||||||
def test_set_contents_with_html_title( self ):
|
def test_set_contents_with_html_title( self ):
|
||||||
|
@ -62,6 +65,7 @@ class Test_note( object ):
|
||||||
assert self.note.startup == self.startup
|
assert self.note.startup == self.startup
|
||||||
assert self.note.deleted_from_id == None
|
assert self.note.deleted_from_id == None
|
||||||
assert self.note.rank == self.rank
|
assert self.note.rank == self.rank
|
||||||
|
assert self.note.user_id == self.user_id
|
||||||
assert self.note.creation == self.creation
|
assert self.note.creation == self.creation
|
||||||
|
|
||||||
def test_set_contents_with_multiple_titles( self ):
|
def test_set_contents_with_multiple_titles( self ):
|
||||||
|
@ -80,6 +84,7 @@ class Test_note( object ):
|
||||||
assert self.note.startup == self.startup
|
assert self.note.startup == self.startup
|
||||||
assert self.note.deleted_from_id == None
|
assert self.note.deleted_from_id == None
|
||||||
assert self.note.rank == self.rank
|
assert self.note.rank == self.rank
|
||||||
|
assert self.note.user_id == self.user_id
|
||||||
assert self.note.creation == self.creation
|
assert self.note.creation == self.creation
|
||||||
|
|
||||||
def test_set_summary( self ):
|
def test_set_summary( self ):
|
||||||
|
@ -96,6 +101,7 @@ class Test_note( object ):
|
||||||
assert self.note.startup == self.startup
|
assert self.note.startup == self.startup
|
||||||
assert self.note.deleted_from_id == None
|
assert self.note.deleted_from_id == None
|
||||||
assert self.note.rank == self.rank
|
assert self.note.rank == self.rank
|
||||||
|
assert self.note.user_id == self.user_id
|
||||||
assert self.note.creation == self.creation
|
assert self.note.creation == self.creation
|
||||||
|
|
||||||
def test_set_notebook_id( self ):
|
def test_set_notebook_id( self ):
|
||||||
|
@ -135,6 +141,7 @@ class Test_note( object ):
|
||||||
assert d.get( "summary" ) == self.summary
|
assert d.get( "summary" ) == self.summary
|
||||||
assert d.get( "title" ) == self.title
|
assert d.get( "title" ) == self.title
|
||||||
assert d.get( "deleted_from_id" ) == None
|
assert d.get( "deleted_from_id" ) == None
|
||||||
|
assert d.get( "user_id" ) == self.user_id
|
||||||
assert d.get( "creation" ) == self.note.creation
|
assert d.get( "creation" ) == self.note.creation
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,6 +154,7 @@ class Test_note_blank( Test_note ):
|
||||||
self.notebook_id = None
|
self.notebook_id = None
|
||||||
self.startup = False
|
self.startup = False
|
||||||
self.rank = None
|
self.rank = None
|
||||||
|
self.user_id = None
|
||||||
self.creation = None
|
self.creation = None
|
||||||
self.delta = timedelta( seconds = 1 )
|
self.delta = timedelta( seconds = 1 )
|
||||||
|
|
||||||
|
@ -162,4 +170,5 @@ class Test_note_blank( Test_note ):
|
||||||
assert self.note.startup == False
|
assert self.note.startup == False
|
||||||
assert self.note.deleted_from_id == None
|
assert self.note.deleted_from_id == None
|
||||||
assert self.note.rank == None
|
assert self.note.rank == None
|
||||||
|
assert self.note.user_id == None
|
||||||
assert self.note.creation == None
|
assert self.note.creation == None
|
||||||
|
|
|
@ -10,10 +10,11 @@ class Test_notebook( object ):
|
||||||
self.trash_id = "18"
|
self.trash_id = "18"
|
||||||
self.name = u"my notebook"
|
self.name = u"my notebook"
|
||||||
self.trash_name = u"trash"
|
self.trash_name = u"trash"
|
||||||
|
self.user_id = u"me"
|
||||||
self.delta = timedelta( seconds = 1 )
|
self.delta = timedelta( seconds = 1 )
|
||||||
|
|
||||||
self.trash = Notebook.create( self.trash_id, self.trash_name, read_write = False, deleted = False )
|
self.trash = Notebook.create( self.trash_id, self.trash_name, read_write = False, deleted = False, user_id = self.user_id )
|
||||||
self.notebook = Notebook.create( self.object_id, self.name, trash_id = self.trash.object_id, deleted = False )
|
self.notebook = Notebook.create( self.object_id, self.name, trash_id = self.trash.object_id, deleted = False, user_id = self.user_id )
|
||||||
self.note = Note.create( "19", u"<h3>title</h3>blah" )
|
self.note = Note.create( "19", u"<h3>title</h3>blah" )
|
||||||
|
|
||||||
def test_create( self ):
|
def test_create( self ):
|
||||||
|
@ -23,6 +24,7 @@ class Test_notebook( object ):
|
||||||
assert self.notebook.read_write == True
|
assert self.notebook.read_write == True
|
||||||
assert self.notebook.trash_id == self.trash_id
|
assert self.notebook.trash_id == self.trash_id
|
||||||
assert self.notebook.deleted == False
|
assert self.notebook.deleted == False
|
||||||
|
assert self.notebook.user_id == self.user_id
|
||||||
|
|
||||||
assert self.trash.object_id == self.trash_id
|
assert self.trash.object_id == self.trash_id
|
||||||
assert datetime.now( tz = utc ) - self.trash.revision < self.delta
|
assert datetime.now( tz = utc ) - self.trash.revision < self.delta
|
||||||
|
@ -30,6 +32,7 @@ class Test_notebook( object ):
|
||||||
assert self.trash.read_write == False
|
assert self.trash.read_write == False
|
||||||
assert self.trash.trash_id == None
|
assert self.trash.trash_id == None
|
||||||
assert self.trash.deleted == False
|
assert self.trash.deleted == False
|
||||||
|
assert self.trash.user_id == self.user_id
|
||||||
|
|
||||||
def test_set_name( self ):
|
def test_set_name( self ):
|
||||||
new_name = u"my new notebook"
|
new_name = u"my new notebook"
|
||||||
|
@ -60,5 +63,6 @@ class Test_notebook( object ):
|
||||||
assert d.get( "trash_id" ) == self.trash.object_id
|
assert d.get( "trash_id" ) == self.trash.object_id
|
||||||
assert d.get( "read_write" ) == True
|
assert d.get( "read_write" ) == True
|
||||||
assert d.get( "deleted" ) == self.notebook.deleted
|
assert d.get( "deleted" ) == self.notebook.deleted
|
||||||
|
assert d.get( "user_id" ) == self.notebook.user_id
|
||||||
assert d.get( "object_id" ) == self.notebook.object_id
|
assert d.get( "object_id" ) == self.notebook.object_id
|
||||||
assert datetime.now( tz = utc ) - d.get( "revision" ) < self.delta
|
assert datetime.now( tz = utc ) - d.get( "revision" ) < self.delta
|
||||||
|
|
Reference in New Issue
Block a user