ef core db-migraions create table into tablespace - oracle

Currently I'm evaluate using the entity framework core migration feature for my projects. But in our oracle database we create tables in different tablespaces.
Unfortunately I couldn't find any solution how I can configure my generated migrations to create a table in a predefined tablespace. Is there any way?
migrationBuilder.CreateTable(
name: "MyTable",
columns: table => new
{
ID = table.Column<Guid>(type: "RAW(16)", nullable: false),
SOME_ID= table.Column<Guid>(type: "RAW(16)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PATIENT", x => x.ID);
});
Where can I add the tablespace?
Can I do any configs in my dbContext modelBuilder?
Update
I ended up doing the user-approach suggested by David Browne.

Since you are using EF Core, have you tried setting the tablespace in the OnModelCreating method, using modelBuilder.UseTablespace("...")?

Related

How to access data of a table (on which VPD is applied) in the PDB of another schema using PDB User?

I want access data of VPD table outside of its Schema Database. In other words I want to access data of a VPD tables into PDB of another Schema.
Let say database(CDB) name is DEVDB.
Now, Lets consider I have created a schema in DEVDB called : VPDSchema
I created two tables in VPDSchema:
1) DBNAME(DB_Name)
2) DBUSER(DB_Name, Username)
Now I created a Table in VPDSchema called: VPDTable ( data is to filtered on basis of i.e.DBName Column)
So the details are:
Schema Name: VPDSchema
Tables Name: VPDTable
User: VPDSchema_User
Password:******
DataBase:DEVDB
Now I applied below Function and Policy on VPDTable inside VPDSchema
Function: VPDFunction
//Matches from DBUSER &
Return Respective DB
//POLICY
BEGIN
SYS.DBMS_RLS.ADD_POLICY(
object_schema => 'VPDSchema',
object_name => 'VPDTable',
policy_name => 'policy_vpd1',
function_schema => 'vpdSchema',
policy_function => 'vpdFuction',
statement_types => 'select'
);
END;
/
Now let's consider I have created another schema Called: UserSchema
So,
Schema Name : UserSchema
User : UsersSchema_User
password : *******
DataBase : DEVDB
Now,
I created a PDB for a specific user on for this schema (UserSchema)
PDB Created : PDBDB
PDB created for : UserSchema
username : UserSchema_User
password : ****
DataBase : PDBDB
Now the problem is: When I create view of VPDtable inside Userschema for UserSchema_user#DEVDB, I can view data of it as both share same CDBC (DEVDB)
BUT when I create view of VPDtable for inside PDB like userSchema_user#PDBDB, it return 0 records
I tried adding policy in UserSchema but it didn't work.
I am stuck here, please help

Room Persistence Library - CREATE VIEW

I need to use a SQL VIEW in a query using Room Persistence Library.
Using Commonsware's answer here I've been able to run a raw SQL statement to create the view during DB creation.
Room.databaseBuilder(context, MyDatabase.class, DB_NAME)
.addCallback(new RoomDatabase.Callback() {
#Override
public void onCreate(#NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
db.execSQL("CREATE VIEW view_name " +
"AS SELECT [...] "
);
}
})
.build();
The VIEW is actually created on the SQLite DB and works fine, but I cannot refer to the it in my Dao's #Query because I get a compile-time error:
Error:(100, 48) error: There is a problem with the query: [SQLITE_ERROR] SQL error or missing database (no such table: view_name)
Any idea on how to let Room to know about my view or to ignore the error?
UPDATE 17/12/2018
Version 2.1.0 and higher of the Room persistence library now provides support for SQLite database views:
https://developer.android.com/training/data-storage/room/creating-views
(see D-D's comment)
UPDATE 15/12/2017
Be aware that this solution actually breaks DB migrations.
Problem is with the Entity primary key that obviously doesn't exist on the view, so migration is not valid.
See CommonsWare's comment for a possible hacky workaround.
ORIGINAL ANSWER
It seems that this is not possible at the moment using Room.
Anyway I've done it using a workaround: I've created an Entity with the same name and columns as the view (only the name is actually mandatory), this will create a table on DB and allow you to use that table name in queries without compile-time errors.
Then during Room DB creation I DROP this entity's table just before the CREATE VIEW.
Room
.databaseBuilder(context, DueDatabase.class, DB_NAME)
.addCallback(new RoomDatabase.Callback() {
#Override
public void onCreate(#NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
//Drop the fake table and create a view with the same name
db.execSQL("DROP TABLE view_name");
db.execSQL("CREATE VIEW view_name " +
"AS SELECT [...]"
);
}
})
.build();

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());
}

Entity Framework 5 (pre-release) newbie issue about entity relations, etc

I looked at this SO question.
I want to do something similar in EF 5. I don't see the ForeignKey attribute but instead an Association attribute in EF5.
Also, can someone explain what this does/means :
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Match>()
.HasRequired(m => m.HomeTeam)
.WithMany(t => t.HomeMatches)
.HasForeignKey(m => m.HomeTeamId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Match>()
.HasRequired(m => m.GuestTeam)
.WithMany(t => t.AwayMatches)
.HasForeignKey(m => m.GuestTeamId)
.WillCascadeOnDelete(false);
}
This is the explanation :
Primary keys are mapped by default convention. Team must have two
collection of matches. You can't have single collection referenced by
two FKs. Match is mapped without cascading delete because it doesn't
work in these self referencing many-to-many.
What I want to do is very similar to the example in the link but I don't know :
When I need to modify DbContext
When the primary keys will link to each other
When I need to explicitly use Association to create the relationship
Any explanation is appreciated.
Okay so... I can't answer the ForeignKey attribute question on EF beta for I haven't had the chance to check it out yet.
However...
modelBuilder.Entity<Match>() - Take the entity "Match" and perform following operations on it
.HasRequired(m => m.HomeTeam) - The entity needs to have a non-null navigation HomeTeam...
.WithMany(t => t.HomeMatches) - ... which has a subset of Matches by navigation HomeMatches
.HasForeignKey(m => m.HomeTeamId) ... and the associating foreign key is HomeTeamId on Match
.WillCascadeOnDelete(false); ... and don't cascade when the entity is deleted.
That's the beauty of LINQ, it's more often than not self-documenting.
Now, as for your three questions...
Only modify DbContext when you are changing your model relations or adding/deleting an entity. If you're adding, you need to do a
public DbSet Entities { get; set;
And remove it if deleting, etc.
Primary keys don't link to each other. Foreign Keys link to Primary Keys. By convention, if you have a ProjectId, a navigation object called Project and another entity called Project with a property called Id, it will automatically map ProjectId from the first entity to the Id of Project entity and give the Project entity as a navigation item to first entity when you fetch data from the DB via EF:
Only if you need non-convention based relationships. Ie, your primary keys are along the lines of "tblId" or "ParentId" instead of "Id" and "ProjectId", for example. Or you need a different kind of behaviour on some items, such as cascading on deletion for only select entities.
In EF 5, if you're using Migrations, you can alter the migration code to not implement the cascade delete:
CreateTable(
"dbo.Match",
c => new
{
MatchId = c.Long(nullable: false, identity: true),
Description = c.String(),
HomeTeamId = c.Long(nullable: false),
})
.PrimaryKey(t => t.MatchId)
.ForeignKey("dbo.Team", t => t.HomeTeamId, cascadeDelete: false)
.Index(t => t.MatchId)
.Index(t => t.HomeTeamId);
}
Or something like that.

Custom columns in list view in Symfony admin generator

tl;dr: I need to show data from two different tables in the list view of the Symfony admin generator (preferably via a JOIN statement)
I'm using the sfDoctrineGuardPlugin to manage the users of my app. Each user also has their own profile that they can fill out. The schema (schema.yml) for the profile table looks like this:
sfGuardUserProfile:
connection: doctrine
tableName: sf_guard_user_profile
columns:
sf_guard_user_id: integer(8)
client_id: string(128)
relations:
sfGuardUser:
local: sf_guard_user_id
foreign: id
foreignType: one
onDelete: CASCADE
Right now table is a client_id and a foreign key to the id column on the sfGuardUser table.
(Yes, I know I need an id column in there just for DB accessibility, and more is coming later)
I've created an admin for my profile table using the Symfony admin generator. I would like my list view on the admin to look like this (generator.yml):
config:
...
list:
title: Clients
display: [client_id, sf_guard_user_id, username]
table_method: retrieveProfileList
However, my username column does not work, and I receive a Doctrine_Record_UnkownPropertyException of:
Unknown record property / related component "username" on "sfGuardUserProfile"
I was hoping a custom table_method to populate the data for the list view would help me, but my table method (in lib/model/sfGuardUserProfileTable.class.php) does not seem to help. I followed an example in the Symfony Book, and this is the method:
public static function retrieveProfileList(Doctrine_Query $q)
{
$rootAlias = $q->getRootAlias();
$q->leftJoin($rootAlias . '.sfGuardUser id');
return $q;
}
Any ideas on how to have the Symfony admin generator display a list view based on a join? Or, alternatively, how to pull from a separate model?
I have answered my own question!
I changed the join method on my sfGuardUserProfileTable class to something I could better understand (thanks to this helpful link):
public static function retrieveProfileList(Doctrine_Query $q)
{
return $q->select('r.*, u.username')
->leftJoin('r.sfGuardUser u');
}
And threw in a getUsername method in my sfGuardUserProfile model class
public function getUsername()
{
return $this->sfGuardUser->username;
}
Thanks for being my rubber duck, SO!

Resources