Rosetta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
open.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file basic/database/open.cc
11 /// @brief Functions for opening database files
12 /// @author Stuart G. Mentzer (Stuart_Mentzer@objexx.com)
13 
14 
15 // Unit headers
16 #include <basic/database/open.hh>
17 #include <basic/Tracer.hh>
18 
19 // Project headers
20 #include <basic/options/keys/in.OptionKeys.gen.hh>
21 #include <basic/options/option.hh>
22 
23 // Utility headers
24 #include <utility/io/izstream.hh>
26 #include <utility/file/PathName.hh>
28 
29 // C++ headers
30 #include <cstdlib>
31 #include <iostream>
32 
33 #if defined(MAC) || defined(__APPLE__) || defined(__OSX__) || defined(linux) || defined(__linux__) || defined(__linux)
34 // POSIX specific headers
35 #include <pwd.h>
36 #endif
37 
38 using basic::T;
39 
40 //Auto Headers
41 #include <utility/vector1.hh>
42 
43 
44 using basic::Error;
45 using basic::Warning;
46 
47 namespace basic {
48 namespace database {
49 
50 static THREAD_LOCAL basic::Tracer TR( "basic.io.database" );
51 
52 
53 /// @brief Open a database file on a provided stream
54 bool
56  utility::io::izstream & db_stream,
57  std::string const & db_file,
58  bool warn /* = true */
59 )
60 {
61  using namespace utility::excn;
62 
63  if ( db_stream.good() ) {
64  db_stream.close();
65  db_stream.clear();
66  }
67  if ( db_file.length() == 0 ) {
68  throw EXCN_Msg_Exception("Unable to open database file ''");
69  return false;
70  }
71 
72  db_stream.open( full_name( db_file, warn ) );
73 
74  if ( db_stream ) { // Open succeeded
75  TR << "Database file opened: " << db_file << std::endl;
76  return true;
77  } else { // Open failed
78  std::stringstream err_msg;
79  err_msg
80  << "Database file open failed for: \"" << db_file << "\"" << std::endl;
81  throw EXCN_Msg_Exception(err_msg.str());
82 
83 #ifdef __native_client__
84  throw( "ERROR: Database file open failed for: " + db_file );
85 #endif
86  db_stream.close();
87  db_stream.clear();
88  return false;
89  }
90 }
91 
92 
93 /// @brief Full-path database file name
94 std::string
96  std::string const & db_file,
97  bool warn // = true
98 )
99 {
100  using namespace basic::options;
101  using namespace basic::options::OptionKeys;
102 
103  for ( size_t i = 1, i_end = option[ in::path::database ]().size(); i <= i_end; ++i ) {
104  std::string fname = option[ in::path::database ](i).name() + db_file;
105  if ( utility::file::file_exists(fname) || utility::file::file_exists(fname + ".gz") ) return fname;
106  }
107  // Don't exit -- sometimes caller wants to check if file exists (e.g. Dunbrack .bin file)
108  //utility_exit_with_message("Unable to locate database file "+db_file);
109  if ( warn ) Warning() << "Unable to locate database file " << db_file << std::endl;
110  return option[ in::path::database ](1).name() + db_file;
111 }
112 
113 /// @brief Does cache file (absolute path) exist?
114 /// if dir_only is true, will return true if the cache file could be created.
115 bool
117  std::string const & cache_file,
118  bool dir_only
119 ) {
120  if ( ! dir_only ) {
121  bool exists = (utility::file::file_exists(cache_file) || utility::file::file_exists(cache_file + ".gz") );
122  if ( TR.Debug.visible() && exists ) {
123  TR.Debug << "Using '" << cache_file << "' as the cached file." << std::endl;
124  }
125  return exists;
126  } else {
127  // Does the directory exist/can it be created?
128  std::string cache_dir = utility::file::FileName( cache_file ).path();
129  if ( ! utility::file::create_directory_recursive( cache_dir ) ) {
130  return false;
131  }
132  // Can we write a file in the directory?
133  // Note that we *don't* want to try actually writing the actual file, due to race conditions.
134  std::string tempfilename( utility::file::create_temp_filename( cache_dir, "writability_check" ) );
135  std::ofstream tempfile( tempfilename.c_str() );
136  bool usable = tempfile.good();
137  tempfile.close();
138  utility::file::file_delete(tempfilename); // Has internal file exist checks.
139  if ( TR.Debug.visible() && usable ) {
140  TR.Debug << "Using '" << cache_dir << "' as a cache directory." << std::endl;
141  }
142  return usable;
143  }
144 }
145 
146 /// @brief Get the (absolute) path to a given cached file.
147 /// If source_file is given, it's the full path to the source database file that's being cached.
148 /// If for_writing is true, will only check that the given file would be creatable.
149 /// Will return an empty string if it can't find a cache file.
150 std::string
152  std::string const & short_name,
153  std::string const & source_file,
154  bool for_writing
155 )
156 {
157  using namespace basic::options;
158  using namespace basic::options::OptionKeys;
159 
160  std::string cache_name;
161 
162  // First try the specified cache directories, if possible.
163  if ( option[ in::path::database_cache_dir ].user() ) {
164  cache_name = std::string(option[ in::path::database_cache_dir ]()) + short_name;
165  if ( find_cache_file( cache_name, for_writing ) ) {
166  return cache_name;
167  }
168  }
169 
170  char const * path = getenv("ROSETTA3_DBCACHE");
171  if ( path && strlen(path) > 0 ) {
172  cache_name = std::string(path) + "/" + short_name;
173  if ( find_cache_file( cache_name, for_writing ) ) {
174  return cache_name;
175  }
176  }
177 
178  // Then try the database directory
179  // We don't iterate through all database directories, because in a multiple directory situation we don't want
180  // to put the cache for one database into a different one
181  if ( source_file.size() != 0 ) {
182  cache_name = utility::file::FileName( source_file ).path() + utility::file::FileName( short_name ).bare_name();
183  if ( find_cache_file( cache_name, for_writing ) ) {
184  return cache_name;
185  }
186  }
187 
188  // No luck? Then fall back to the user's home directories.
189  char const * homedir = getenv("XDG_CONFIG_HOME");
190  if ( ! homedir || strlen(homedir) == 0 ) {
191  homedir = getenv("HOME");
192  }
193 #if defined(MAC) || defined(__APPLE__) || defined(__OSX__) || defined(linux) || defined(__linux__) || defined(__linux)
194  if ( ! homedir || strlen(homedir) == 0 ) {
195  passwd const * unix_pwd( getpwuid(getuid()) );
196  if ( unix_pwd ) {
197  homedir = unix_pwd->pw_dir;
198  }
199  }
200 #endif
201 
202  if ( homedir && strlen(homedir) > 0 ) {
203  cache_name = std::string(homedir) + "/.rosetta/database/" + short_name;
204  if ( find_cache_file( cache_name, for_writing ) ) {
205  return cache_name;
206  }
207  }
208 
209  return "";
210 }
211 
212 } // namespace database
213 } // namespace basic
#define THREAD_LOCAL
bool good() const
Good?
Definition: izstream.hh:572
std::string full_name(std::string const &db_file, bool warn)
Full-path database file name.
Definition: open.cc:95
dictionary size
Definition: amino_acids.py:44
static THREAD_LOCAL basic::Tracer TR("basic.io.database")
BooleanOptionKey const user("options:user")
Definition: OptionKeys.hh:40
bool visible() const
Definition: Tracer.hh:240
Platform independent operations on files (except I/O)
FileName & path(std::string const &path_a)
Path assignment.
Definition: FileName.cc:46
bool find_cache_file(std::string const &cache_file, bool dir_only)
Does cache file (absolute path) exist? if dir_only is true, will return true if the cache file could ...
Definition: open.cc:116
std::string bare_name() const
Bare name (without volume or path or version)
Definition: FileName.hh:398
File name class supporting Windows and UN*X/Linux format names.
Definition: FileName.hh:37
Tracer & T(std::string const &channel, TracerPriority priority)
T is special function for assign tracer property on the static object.
Definition: Tracer.cc:567
common derived classes for thrown exceptions
std::string full_cache_name(std::string const &short_name, std::string const &source_file, bool for_writing)
Get the (absolute) path to a given cached file. If source_file is given, it's the full path to the so...
Definition: open.cc:151
tuple database
void close()
Close the ifstream and reset the state.
Definition: izstream.hh:219
Functions for opening database files.
Tracer & Error(TracerPriority priority=t_error)
Predefined Error tracer.
Definition: Tracer.hh:395
bool open(utility::io::izstream &db_stream, std::string const &db_file, bool warn)
Open a database file on a provided stream.
Definition: open.cc:55
Tracer IO system.
izstream: Input file stream wrapper for uncompressed and compressed files
Definition: izstream.hh:44
Input file stream wrapper for uncompressed and compressed files.
void clear()
Clear the stream(s)
Definition: izstream.hh:202
bool create_directory_recursive(std::string const &dir_path)
Create a directory and its parent directories if they doesn't already exist.
rule< Scanner, options_closure::context_t > options
Definition: Tag.cc:377
int file_delete(std::string const &path)
Delete File.
Tracer & Warning(TracerPriority priority=t_warning)
Predefined Warning tracer.
Definition: Tracer.hh:398
Path name class supporting Windows and UN*X/Linux format names.
vector1: std::vector with 1-based indexing
Class for handling user debug/warnings/errors. Use instance of this class instead of 'std::cout' for ...
Definition: Tracer.hh:134
bool file_exists(std::string const &path)
Does File Exist?
rule< Scanner, string_closure::context_t > name
Definition: Tag.cc:376
Program options global and initialization function.
std::string create_temp_filename(std::string const &dir, std::string const &prefix)
Find an unused random tempfile name with a given prefix (which may include a directory) ...
void open(std::string const &filename_a, std::ios_base::openmode open_mode=std::ios_base::in)
Open a file.
Definition: izstream.cc:34
TracerProxy Debug
Definition: Tracer.hh:262
rule< Scanner, option_closure::context_t > option
Definition: Tag.cc:378