diff --git a/core/config.cpp b/core/config.cpp index 46ceadc..cc41f4e 100755 --- a/core/config.cpp +++ b/core/config.cpp @@ -103,7 +103,6 @@ void Config::AssignValues() data.db_pass = Text("db_pass"); data.base_url = Text("base_url"); data.one_item_is_showed = Bool("one_item_is_showed"); - data.dirs.root.default_item = Int("dir.root.default_item"); data.priv_no_user = Text("priv_no_user"); data.priv_no_group = Text("priv_no_group"); diff --git a/core/content.cpp b/core/content.cpp index fe383c9..aae3d88 100755 --- a/core/content.cpp +++ b/core/content.cpp @@ -154,22 +154,26 @@ void Content::LogUser() void Content::MakeDirectoryStructure() { GetTable::size_type get_table_len = request.get_table.size(); - long parent = -1; + get_index = 0; + request.dir = -1; - for( get_index = 0 ; get_index < get_table_len ; ++get_index) + Item * pdir; + if( !data.dirs.GetRootDir(&pdir) ) + // there is no a root dir + return; + + request.dir = pdir->id; + + for( ; get_index < get_table_len ; ++get_index) { - Item * pdir; - - if( !data.dirs.GetDir(request.get_table[get_index], parent, &pdir) ) + if( !data.dirs.GetDir(request.get_table[get_index], pdir->id, &pdir) ) break; - - parent = pdir->id; + request.cur_dir_table.push_back( *pdir ); } - // parent - last directory (or -1 if none) - request.dir = parent; - data.dirs.GetDirChilds(parent, request.dir_table); + request.dir = pdir->id; + data.dirs.GetDirChilds(request.dir, request.dir_table); } @@ -243,7 +247,7 @@ bool Content::MakeGetCheckDir() long default_id = -1; if( request.cur_dir_table.empty() ) { - default_id = data.dirs.root.default_item; + //default_id = data.dirs.root.default_item; } else { diff --git a/core/db.cpp b/core/db.cpp index 3a183fb..131bd84 100755 --- a/core/db.cpp +++ b/core/db.cpp @@ -932,7 +932,7 @@ void Db::GetDirs(DirContainer & dir_table) AssertConnection(); std::ostringstream query; - query << "select * from core.item left join core.content on item.content_id = content.id where type='0';"; + query << "select * from core.item where type='0';"; r = AssertQuery( query.str() ); AssertResultStatus(r, PGRES_TUPLES_OK); @@ -954,7 +954,6 @@ void Db::GetDirs(DirContainer & dir_table) } ClearResult(r); - } diff --git a/core/dircontainer.cpp b/core/dircontainer.cpp index 4a5cd95..13684ed 100755 --- a/core/dircontainer.cpp +++ b/core/dircontainer.cpp @@ -13,6 +13,17 @@ DirContainer::DirContainer() { + is_root = false; +} + + + +DirContainer::Iterator DirContainer::GetRoot() +{ + if( !is_root ) + return table.end(); + +return table.begin() + root_index; } @@ -40,6 +51,7 @@ bool DirContainer::Empty() } + void DirContainer::PushBack(const Item & item) { bool rebuild_indexes = false; @@ -47,8 +59,21 @@ bool rebuild_indexes = false; if( table.size() == table.capacity() ) rebuild_indexes = true; + + if( item.parent_id == -1 ) + { + if( is_root ) + log << log1 << "DirCont: more than one root dir - skipped, id: " << item.id << logend; + else + { + is_root = true; + root_index = table.size(); + } + } + table.push_back(item); log << log2 << "DirCont: added item, id: " << item.id << ", parent_id: " << item.parent_id << logend; + if( rebuild_indexes ) RebuildIndexes(); diff --git a/core/dircontainer.h b/core/dircontainer.h index 6c81210..050f51d 100755 --- a/core/dircontainer.h +++ b/core/dircontainer.h @@ -32,6 +32,8 @@ public: DirContainer(); + Iterator GetRoot(); + Iterator Begin(); Iterator End(); SizeType Size(); @@ -57,6 +59,12 @@ private: // main table with dirs Table table; + // true if there is a root dir in the table + bool is_root; + + // root dir + SizeType root_index; + // indexes TableId table_id; TableParent table_parent; diff --git a/core/dirs.cpp b/core/dirs.cpp index e1734a0..10a309c 100755 --- a/core/dirs.cpp +++ b/core/dirs.cpp @@ -13,21 +13,55 @@ void Dirs::Clear() { dir_table.Clear(); - - // !! temporarily not clearing - //root.Clear(); - root.id = -1; } + +void Dirs::CheckRootDir() +{ +DirContainer::ParentIterator i; +long roots = 0; + + + for( i=dir_table.FindFirstParent(-1) ; i!=dir_table.ParentEnd() ; i=dir_table.NextParent(i) ) + ++roots; + + if( roots == 0 ) + { + log << log1 << "Dirs: there is no a root dir in the database" << logend; + Clear(); + } + else + if( roots > 1 ) + { + log << log1 << "Dirs: there are more than one root dir in the database" << logend; + Clear(); + } +} + + + + void Dirs::ReadDirs() { Clear(); db.GetDirs(dir_table); + CheckRootDir(); } +bool Dirs::GetRootDir(Item ** item) +{ + DirContainer::Iterator root = dir_table.GetRoot(); + + if( root == dir_table.End() ) + return false; + + *item = &(*root); + +return true; +} bool Dirs::GetDir(const std::string & name, long parent, Item ** item) @@ -60,19 +94,27 @@ return !name.empty(); - +// !! moze lepiej zwracac wskaznik do Item i kiedy nie ma katalogu to zwracac 0 ? bool Dirs::GetDir(const std::string & path, Item ** item) { - long parent = -1; + DirContainer::Iterator root = dir_table.GetRoot(); + + if( root == dir_table.End() ) + // ops, we do not have a root dir + return false; + + Item * pitem = &(*root); + std::string name; const char * s = path.c_str(); - Item * pitem = &root; while( ExtractName(s, name) ) { - if( !GetDir(name, parent, &pitem) ) + if( !GetDir(name, pitem->id, &pitem) ) return false; } + + *item = pitem; @@ -81,7 +123,8 @@ return true; - +// !! ten interfejs jes bylejaki +// !! moze lepiej zwracac id i kiedy nie ma katalogu to -1 (przeciez to jest wartosc ktora nie moze pojawic sie w indeksie) bool Dirs::GetDirId(const std::string & path, long * id) { Item * pitem; @@ -111,10 +154,6 @@ return true; bool Dirs::IsDir(long id) { - if( id == -1 ) - // root directory - return true; - DirContainer::Iterator i = dir_table.FindId(id); if( i == dir_table.End() ) @@ -128,7 +167,7 @@ return true; bool Dirs::GetDirChilds(long parent, std::vector & childs_table) { - if( !IsDir(parent) ) + if( parent != -1 && !IsDir(parent) ) return false; DirContainer::ParentIterator i = dir_table.FindFirstParent(parent); @@ -150,21 +189,23 @@ bool Dirs::MakePath(long id, std::string & path) { DirContainer::Iterator i; - path.clear(); + path = '/'; while( true ) { - if( id == -1 ) - return true; - i = dir_table.FindId(id); if( i == dir_table.End() ) return false; + if( i->parent_id == -1 ) + return true; + id = i->parent_id; - path.insert(path.begin(), '/'); + + path.insert(0, i->url); + path.insert(path.begin(), '/'); } } diff --git a/core/dirs.h b/core/dirs.h index 706455b..604b8c1 100755 --- a/core/dirs.h +++ b/core/dirs.h @@ -29,21 +29,12 @@ private: public: // !! temporarily - // id = -1; - Item root; - - DirContainer dir_table; - - // parent (or -1), item - //typedef std::multimap DirTable; - //DirTable dir_table; - - bool ExtractName(const char * & s, std::string & name); - - + void CheckRootDir(); + + public: @@ -57,6 +48,8 @@ public: bool IsDir(long id); + bool GetRootDir(Item ** item); + bool GetDir(const std::string & path, Item ** item); bool GetDir(const std::string & name, long parent, Item ** item); diff --git a/core/request.cpp b/core/request.cpp index ca493c3..b2d680e 100755 --- a/core/request.cpp +++ b/core/request.cpp @@ -384,7 +384,7 @@ bool Request::HasAccess(const Item & item, int mask) if( session->puser && session->puser->IsMemberOf(item.group_id) ) { - // group + // group return ((item.privileges >> 3) & mask) == mask; } @@ -411,7 +411,7 @@ bool Request::HasReadWriteAccess(const Item & item) } -bool Request::HasExecAccess(const Item & item) +bool Request::HasReadExecAccess(const Item & item) { return HasAccess(item, 5); // r+x } diff --git a/core/request.h b/core/request.h index 4124eb8..0f4931c 100755 --- a/core/request.h +++ b/core/request.h @@ -117,7 +117,7 @@ struct Request bool HasReadAccess(const Item & item); bool HasWriteAccess(const Item & item); bool HasReadWriteAccess(const Item & item); - bool HasExecAccess(const Item & item); + bool HasReadExecAccess(const Item & item); private: