|
|
| version 1.9, 2001/04/26 10:16:07 | version 1.12, 2001/05/17 08:42:22 |
|---|---|
| Line 49 private: | Line 49 private: |
| // SQL_Driver_manager | // SQL_Driver_manager |
| // url: | /// @param request_url protocol://[driver-dependent] |
| // protocol://user:pass@host:port/database | SQL_Connection& SQL_Driver_manager::get_connection(const String& request_url, |
| // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this is driver-dependent | |
| SQL_Connection& SQL_Driver_manager::get_connection(const String& request_owned_url, | |
| Table *protocol2driver_and_client) { | Table *protocol2driver_and_client) { |
| SYNCHRONIZED(true); | SYNCHRONIZED(true); |
| Pool& pool=request_owned_url.pool(); // request pool | Pool& pool=request_url.pool(); // request pool |
| // we have table for locating protocol's library | // we have table for locating protocol's library |
| if(!protocol2driver_and_client) | if(!protocol2driver_and_client) |
| PTHROW(0, 0, | PTHROW(0, 0, |
| &request_owned_url, | &request_url, |
| "$SQL:drivers table must be defined"); | "$SQL:drivers table must be defined"); |
| // services associated with request | |
| SQL_Driver_services_impl& services= | |
| *new(pool) SQL_Driver_services_impl(pool, request_url); | |
| // first trying to get cached connection | // first trying to get cached connection |
| if(SQL_Connection *result=get_connection_from_cache(request_owned_url)) | if(SQL_Connection *result=get_connection_from_cache(request_url)) |
| if(result->ping()) | if(result->ping()) { |
| result->set_services(&services); | |
| return *result; | return *result; |
| else | } else |
| result->disconnect(); // kill unpingabe=dead connection | result->disconnect(); // kill unpingabe=dead connection |
| // no cached connection | // no cached connection |
| int pos=request_owned_url.pos("://", 3); | int pos=request_url.pos("://", 3); |
| if(pos<0) | if(pos<0) |
| PTHROW(0, 0, | PTHROW(0, 0, |
| &request_owned_url, | &request_url, |
| "no protocol specified"); // NOTE: not THROW, but PTHROW | "no protocol specified"); // NOTE: not THROW, but PTHROW |
| // make url C-string on global pool | // make global_url C-string on global pool |
| char *url_cstr=(char *)malloc(MAX_STRING); | char *request_url_cstr=request_url.cstr(String::UL_AS_IS); |
| strncpy(url_cstr, request_owned_url.cstr(String::UL_AS_IS), MAX_STRING); | char *global_url_cstr=(char *)malloc(strlen(request_url_cstr)+1); |
| // make url string on global pool | strcpy(global_url_cstr, request_url_cstr); |
| String& url=*new(this->pool()) String(this->pool(), url_cstr); | // make global_url string on global pool |
| String& global_url=*new(this->pool()) String(this->pool(), global_url_cstr); | |
| char *protocol_cstr=lsplit(&url_cstr, ':'); | char *request_protocol_cstr=lsplit(&request_url_cstr, ':'); |
| String& protocol=*new(this->pool()) String(this->pool(), protocol_cstr); | // skip "//" after ':' |
| while(*request_url_cstr=='/') | |
| // skip // after : | request_url_cstr++; |
| while(*url_cstr=='/') | // make global_protocol C-string on global pool |
| url_cstr++; | char *global_protocol_cstr=(char *)malloc(strlen(request_protocol_cstr)+1); |
| strcpy(global_protocol_cstr, request_protocol_cstr); | |
| // make global_protocol string on global pool | |
| String& global_protocol=*new(this->pool()) String(this->pool(), | |
| global_protocol_cstr); | |
| SQL_Driver *driver; | SQL_Driver *driver; |
| const String *dlopen_file_spec=0; | const String *dlopen_file_spec=0; |
| // first trying to get cached driver | // first trying to get cached driver |
| if(!(driver=get_driver_from_cache(protocol))) { | if(!(driver=get_driver_from_cache(global_protocol))) { |
| // no cached | // no cached |
| const String *library=0; | const String *library=0; |
| if(protocol2driver_and_client->locate(0, protocol)) { | if(protocol2driver_and_client->locate(0, global_protocol)) { |
| if(!(library=protocol2driver_and_client->item(1)) || library->size()==0) | if(!(library=protocol2driver_and_client->item(1)) || library->size()==0) |
| PTHROW(0, 0, | PTHROW(0, 0, |
| protocol2driver_and_client->origin_string(), | protocol2driver_and_client->origin_string(), |
| "driver library column for protocol '%s' is empty", protocol_cstr); | "driver library column for protocol '%s' is empty", |
| request_protocol_cstr); | |
| if(!(dlopen_file_spec=protocol2driver_and_client->item(2)) || dlopen_file_spec->size()==0) | if(!(dlopen_file_spec=protocol2driver_and_client->item(2)) || dlopen_file_spec->size()==0) |
| PTHROW(0, 0, | PTHROW(0, 0, |
| protocol2driver_and_client->origin_string(), | protocol2driver_and_client->origin_string(), |
| "client library column for protocol '%s' is empty", protocol_cstr); | "client library column for protocol '%s' is empty", |
| request_protocol_cstr); | |
| } else | } else |
| PTHROW(0, 0, | PTHROW(0, 0, |
| &url, | &request_url, |
| "undefined protocol '%s'", protocol_cstr); | "undefined protocol '%s'", |
| request_protocol_cstr); | |
| const char *filename=library->cstr(String::UL_FILE_NAME); | const char *filename=library->cstr(String::UL_FILE_NAME); |
| lt_dlhandle handle=lt_dlopen(filename); | lt_dlhandle handle=lt_dlopen(filename); |
| Line 146 SQL_Connection& SQL_Driver_manager::get_ | Line 157 SQL_Connection& SQL_Driver_manager::get_ |
| dlopen_file_spec_cstr, error); | dlopen_file_spec_cstr, error); |
| // cache it | // cache it |
| put_driver_to_cache(protocol, *driver); | put_driver_to_cache(global_protocol, *driver); |
| } | } |
| // services associated with request | |
| SQL_Driver_services_impl& services= | |
| *new(pool) SQL_Driver_services_impl(pool, url); | |
| // allocate in global pool | // allocate in global pool |
| // associate with services[request], deassociates at close | // associate with services[request], deassociates at close |
| SQL_Connection& result= | SQL_Connection& result= |
| *new(this->pool()) SQL_Connection(this->pool(), | *new(this->pool()) SQL_Connection(this->pool(), |
| url, *driver, services, url_cstr); | global_url, *driver, services, request_url_cstr); |
| return result; | return result; |
| } | } |
| Line 194 SQL_Connection *SQL_Driver_manager::get_ | Line 201 SQL_Connection *SQL_Driver_manager::get_ |
| return 0; | return 0; |
| } | } |
| /// @todo cache expiration[use SQL_Driver::disconnect], pinging. | /// @todo cache expiration[use SQL_Driver::disconnect] |
| void SQL_Driver_manager::put_connection_to_cache(const String& url, | void SQL_Driver_manager::put_connection_to_cache(const String& url, |
| SQL_Connection& connection) { | SQL_Connection& connection) { |
| Stack *connections; | Stack *connections; |