override database name for database class - codeigniter

I need to read database name from session (browser) and use this name for global db connection (all db functions) instead of name stored in database.php. How should I override/extend MY_Loader.php to be able to do this?

Hmmm...why do you want to do this? I have never known this to be done. You could extend the database class, to check the session for the database name, or I would maybe give this a try;
Before you load your database, you could load your session, and use that to define the database config;
$config['hostname'] = $this->session->userdata('db_hostname');
$config['username'] = $this->session->userdata('db_username');
$config['password'] = $this->session->userdata('db_password');
$config['database'] = $this->session->userdata('db_database');
// Now, load the database
$this->load->database($config);

Related

Use Oracle's DBMS_SESSION.set_context in Entity Framework Core

I have the need to show on my .net core program an Oracle view that in the database has some columns filtered by
... WHERE dictionary.LANGUAGE = SYS_CONTEXT ('CLIENTCONTEXT', 'LANGUAGE');
Obviously fetching the data directly on the application makes those columns return a null value.
I would need to implement something like this
OracleCommand cmd = new OracleCommand(String.Format("BEGIN DBMS_SESSION.SET_CONTEXT('CLIENTCONTEXT', 'LANGUAGE', '{0}'); END;", ActualLanguage), ORACLEconn as OracleConnection);
cmd.ExecuteNonQuery();
How would I go about implementing the code using Entity Framework Core? Would I need to call it once on the model creation or every time I create a new DbContext?
Thank you.
If you have a DbContext constructor that's only used when you want the session context set, you can force the connection open, and it will remain open until your DbContext is disposed. eg
public Db(DbContextOptions opts) : base(opts)
{
this.Database.OpenConnection();
this.Database.ExecuteSqlRaw("BEGIN DBMS_SESSION.SET_CONTEXT('CLIENTCONTEXT', 'LANGUAGE', 'whatever'); END;");
}
Or you can use an Interceptor to run the command every time a connection is opened.

Laravel - Multi-tenancy - One database multiple tables

I want to create a multi tenancy application using Laravel. I am using the one database, multiple tenant tables database architecture.
I want to create a new set of tenant related tables dynamically, whenever someone registers a new tenant account.
Please consider the following:
tenants table holds all the client registrations. Each tenant will have dedicated tables only for them. In this example every tenant has their own dedicated customer table.
Ex:
tenant01's tables will have tenant01 prefix. (tenant01.customer - only tenant01's customers)
tenant02's tables will have tenant02 prefix. (tenant02.customer - only tenant02's customers)
I don't want to use multiple databases as they are costly and I don't want to use one table for all the tenants, as there will be lots of customers/products etc in the system.
I'm planning to identify the tenant at the logging process and set the tenant name(or a code/Id) in a session. ex: tenant440
After that, in all customer related eloquent model classes, I could dynamically append that prefix (ex: tenant440) into the table name like this:
<?php
class Customer extends Eloquent {
protected $tenant_name = //get name/code from the session. ex: tenant440
//table name will become tenant440.'customers'
protected $table = $tenant_name.'customers';
?>
Is this a correct way to achieve this? What is the simplest to do this? Do you know any kind of resources/packages/libraries for this?
Thanks in advance!
You can set tenant name as a prefix in your database file:
Config::set('database.connections.mysql.prefix',$tenantName); // assuming 'mysql' is the default database connection name
I recommend to put it inside a filter
// routes.php
Route::group(array('before'=>'setTablePrefix'), function($noob)
{
Route::resource('customers', 'CustomersController');
Route::controller('sales', 'SalesController');
});
Route::get('/login',array('as' => 'login', 'uses' => 'UserController#getLogin'));
// filters.php
Route::filter('setTablePrefix', function($route, $request)
{
if (!Session::has('prefixTable'))
App::abort(404);
Config::set('database.connections.mysql.prefix',Session::get('prefixTable'));
});
To get data from all tables, you probably need two queries (or one if you use Session)
$tenants = DB::table('tenants')->lists('name'); // you can set it in Session
if($tenants){
$allCustomers = DB::table($tenants[0].'.customers');
for ($i = 1; $i < count($tenants); $i++) {
$allCustomers->unionall(DB::table($tenants[$i].'.customers'));
}
var_dump($allCustomers->get());
}

How to Persist data using session variable in mvc3 razor view?

I am working in MVC3 Application with Razor. In my Account controller after validating the user, i am getting the user ClientID from Database. Here i want to persist ClientID in Session variable. which was using across the all controller and Razor view.
I have no idea as to what is the best way to implement this.OR How to persist data in the session variable. And how to use persisted data in the session variable in across the controller.
Thanks for your help..
I usually write a Session wrapper that allows me easy access to it in the future:
public class SessionData
{
const string ClientId_KEY = "ClientId";
public static int ClientId
{
get { return HttpContext.Current.Session[ClientId_KEY] != null ? (int)HttpContext.Current.Session[ClientId_KEY] : 0; }
set { HttpContext.Current.Session[ClientId_KEY] = value; }
}
}
After that you can access it from anywhere like this:
int clientId = SessionData.ClientId;
If you want you can use whole objects in Session like this.
Or you can set it like so: SessionData.ClientId = clientId;
If you are using ASP.NET Forms Authentication, the user name is already stored in a cookie. You can access it from the Controller via
Controller.User.Identity.Name
It's possible to store the user ID as the user name. When you call something like
FormsAuthentication.RedirectFromLoginPage
Give it the ID instead of a name. The ID can then be found using the method above and no extra session data is necessary. If you want to store something in the session, just call
Session["UserID"] = value;
From your controller.

Something weird about express session store

If I store an object in session like this:
user.name = "Kelvin"; // user is an object pass by "mongoose" findOne's callback.
req.session.user = user;
console.log(req.session.user.name); // Kelvin
and after that, I access "user" in other routes of express:
app.get("/somepath", function(req, resp) {
console.log(req.session.user.name); // undefined
});
I want to know why req.session.user.name is undefined besides the function I set it?
After looking into mongoose source code I can say that this is because how mongoose models and session works. When you call req.session.user = user then req.session.user points to the object but actually the data needs to be stored somewhere (like memory or Redis).
In order to do that Express calls JSON.stringify(sess) and string is stored in memory. Here's where mongoose enters. Models are constructed in such a way, that when you stringify them only attributes predefined in Schema are included. So when you set req.session.user = user Express stringifies user (you loose name attribute) and saves the data. When you call req.session.user in another route Express parses stringified data and you obtain object without name attribute.
Now how to fix this? There are several ways.
Add name attribute to the Schema;
Define new literal object for user:
var newuser = { id: user.id, name : "Kelvin", pwd: user.pwd, etc. };
req.session.user = newuser;
Store name in another field: req.session.name = "Kelvin"; (the best solution imho)
By the way: You shouldn't hold the user object in session. What if some other user like administrator makes changes to the user object? You won't see them at all. I advice holding only the id of the user in session and make custom middleware to load user from DB and store it in request object.

In Linq to SQL, why does assigning a related entity create a ChangeSet insert?

Why is the following adding an Insert (of the new Address) to the DataContent ChangeSet, and how can I stop it from doing so?
var db = new DataClasses1DataContext();
var a = new Address();
a.StateProvince = db.StateProvinces.First();
Console.WriteLine(db.GetChangeSet().Inserts.Count);
Address a = new Address();
This creates a new instance of Address. It is not associated with a datacontext in any way.
db.StateProvinces.First();
This loads an instance of StateProvince. The instance is tracked by the datacontext that loaded it (db). db is waiting for notifications of changes from this instance.
a.StateProvince =
Here is assignment to a property. If you inspect the autogenerated property "StateProvince", you'll see that it also updates the related property "Addresses" on the StateProvince instance. Now the StateProvince instance has changed. This causes db to be notified, and as a result - the address instance is now tracked by db as a new, ready-to-insert instance.
The simplest way out of this is, before using db, set:
db.ObjectTrackingEnabled = false;
PS. var is awesome like hotdogs are awesome.
Because the data context knows about the state province, it automatically queues up Address for an insertion. As long as you don't submit it, the address will never be created. Also, to work around it, set:
Address.StateProvinceID = db.StateProvinces.First().StateProvinceID;
If you can work without a direct object reference. There is no direct way to detach an entity in LINQ to SQL, except through PLINQO (http://plinqo.com/default.aspx?AspxAutoDetectCookieSupport=1).
It is doing it because you are retreiving a "StateProvince" and setting the foreign key on the new address to the existing state province, becuase the address is new then the change set will build an insert for it becuase i suspect you have changed the state province by impicitly adding the new address to the Addresses collection on the StateProvince entity. You could try removing the child property from the assoication as it is probably not usefull to have a collections of associated addresses on a state province entity.
You could also try the following:
DataClasses1DataContext db = new DataClasses1DataContext();
db.ObjectTrackingEnabled = false;
Address a = new Address();
a.StateProvince = db.StateProvinces.First();
You may also notice i have removed your blatant abuse of var ;-)

Resources