How instantiate a typeorm entity with values without db connection? - typeorm

I did this UserFactory:
export class UserFactory {
create(values = {}): User {
return User.create({
// defaults
name: 'Jerry',
age: 99,
// overrides
...values,
})
}
}
It is my understanding that Entity.create does not persist the entity in my db, it only creates the instance (I'm using the BaseEntity/ORM pattern). This is precisely what I want. However, it still requires a connection to work. In my tests I need to do something like:
const connection = await db()
const user = new UserFactory().create()
await connection.destroy()
Otherwise, I get DataSource is not set for this entity. I can't understand why a connection is needed when it's not even saving it.
I guess I could use new User() but unfortunately there is no set methods to bulk apply my values then.
How can I set my values and get an entity instance without unnecessary db connections here?

Related

Change the document's unique ID from string to int in firebase realtime using xamarin form

My problem is I want to change the document/table unique ID from string to int in firebase realtime database.
This is how it looks in my database:
.
I want to look like this:
.
This is my code in inserting data to firebase:
public async Task<bool> Save(CUSTOMER customer)
{
//var token = await authProvider.CreateUserWithEmailAndPasswordAsync(customer.CusEmail,customer.CusPassword);&& !string.IsNullOrEmpty(token.FirebaseToken);
var token = await authProvider.CreateUserWithEmailAndPasswordAsync(customer.CusEmail, customer.CusPassword);
var data = await firebaseClient.Child(nameof(CUSTOMER)).PostAsync(JsonConvert.SerializeObject(customer));
if (!string.IsNullOrEmpty(data.Key) && !string.IsNullOrEmpty(token.FirebaseToken))
{
return true;
}
return false;
}
When you call PostAsync, Firebase creates a new child node with its own unique ID for that data. The IDs always have the form that you see in your first screenshot, and there's no way to change that.
To specify your own ID, generate that ID in your client-side application code, pass it to the API as an additional Child() call, and use Put instead of Post. For example:
firebaseClient.Child(nameof(CUSTOMER)).Child("4815").PutAsync(JsonConvert.SerializeObject(customer));
If the number you want to use is based on the existing keys in the database, you'll need to use a transaction to perform the necessary read-then-write sequence.
Since you're considering using numeric keys, I recommend checking out Best Practices: Arrays in Firebase.

Database connection pattern

I use mysql-native. This driver is suppport vibed's connection pool. On dlang newsgroup mysql-native developer Nick Sabalausky wrote:
"If you're using a connection pool, you shouldn't need to worry about closing the connection. The whole point is that the connections stay open until you need to use one again. When your program ends, then connections will close by themselves."
"You create the pool once (wherever/whenever you want to). Then, every time you want to use the database you obtain a connection by calling MySqlPool.lockConnection."
"Calling 'close' will always close the connection. If you got you connection from the pool, then it will automatically return to the pool when you're no longer using it. No need to do anything special for that."
The question about how pool should be done? I have read about singleton pattern and can't unserstand is it this case.
I wrote next code:
database class:
import std.stdio;
import std.string;
import mysql;
import vibe.d;
import config;
import user;
class Database
{
Config config;
MySqlPool mydb;
Connection connection;
this(Config config)
{
this.config = config;
mydb = new MySqlPool(config.dbhost, config.dbuser, config.dbpassword, config.dbname, config.dbport);
}
void connect()
{
if(connection is null)
{
connection = mydb.lockConnection();
}
scope(exit) connection.close();
}
}
users class/struct:
module user;
import mysql;
import vibe.d;
struct User
{
int id;
string login;
string password;
string usergroup;
}
void getUserByName(string login)
{
User user;
Prepared prepared = prepare(connection, `SELECT id, login, password, usergroup from users WHERE login=?`); // need to get connection accessible here to make request to DB
prepared.setArgs(login);
ResultRange result = prepared.query();
if (result.empty)
logWarn(`user: "%s" do not exists`, login);
else
{
Row row = result.front;
user.id = row[0].coerce!(int);
user.login = row[1].coerce!string;
user.password = row[2].coerce!string;
user.usergroup = row[3].coerce!string;
logInfo(`user: "%s" is exists`, login);
}
}
The problem that I can't understand what is proper way to getting access to connection instance. It seems that it's very stupid ideas to create every new database connection class inside users structure. But how to do it's in better way? To make Connection connection global? Is it's good? Or there is more correct way?
scope(exit) connection.close();
Delete that line. It's closing the connection you just received from the pool before the connect function returns. All you're doing there is opening a connection just to immediately close it again.
Change getUserByName to take a connection as an argument (typically as the first argument). Typically, whatever code needs to call getUserByName should either open a connection, or get a connenction from the pool via lockConnection, and then pass that connection to getUserByName and whatever other DB-related functions it needs to use. Then, after your code is done calling getUserByName (and whatever other DB functions it needs to call), you either just don't worry about the connection anymore and let your vibed fiber finish (if you're using vibed and got the connection from a pool) or you close the connection (if you did NOT get the connection from a vibed pool).
One way to do it is to pass the connection to your functions that need it. So you would refactor your getUserByName() to take connection as an argument.
Another alternative is to use the DAO pattern . Constructor of your DAO class would take the connection as one of the main parameters, and all the methods would use it to do the DB operation.

how to get an unsaved entity on server but not for saving?

i need to send my unsaved entity from the client to the server but not for saving changes
but inorder to do a process using the data on the entity and then change some of it's values and pass it back to the client
is this possible?
if not what are my options?
i tried to export the entity and then send it to a method on the webapi controller that gets a JObject but didn't find a way to deserialize it to the server entity
We did have a similar problem and found a solution as follows:
You need to take into consideration the way breeze manages it's objects.
1.Create custom saveBundle.
Consider complex order object.You need to fill your save bundle with each nested object inside order.
Like:
var saveBundle = new Array();
saveBundle.push(order.SaleAccountingInfo);
saveBundle.push(order.CostAccountingInfo);
saveBundle.push(order);
2.Create custom save options, where you can point to your custom Save Method on server
Like:
var so = new breeze.SaveOptions({ resourceName: "BookOrder" });
3.Call standard breeze function and pass it created params
manager.saveChanges(saveBundle, so).fail(function () {
// manager.rejectChanges();TODO check what needed
deferred.resolve(true);
});
On server you need to have you custom function ready and hook some breeze delegates
[HttpPost]
public SaveResult BookOrder(JObject orderBundle)
{
context.BeforeSaveEntityDelegate = OrderBeforeSaveEntity;
context.BeforeSaveEntitiesDelegate = SaveOrder;
context.AfterSaveEntitiesDelegate = BookOrderAfterSave;
try
{
return context.SaveChanges(orderBundle);
}
catch (Exception)
{
throw;
}
}
You can a lot of stuff in first two delegates but it is the last one you are looking for
private void BookOrderAfterSave(Dictionary<Type, List<EntityInfo>> orderSaveMap, List<KeyMapping> orderKeyMappings)
{
var orderEntity = orderSaveMap.Where(c => c.Key == typeof(BL.Orders.Order)).Select(d => d.Value).SingleOrDefault();
BL.Orders.Order order = (BL.Orders.Order)orderEntity[0].Entity; //your entity
//logic here
}
Hope it points to right direction.
we are doing something similar here. it'll save the entity so i'm not sure if this fits your question.
you can do:
entity.entityAspect.setModified()
then issue a saveChange()
then you can do your calculations on the server.
in our case we are using breeze.webapi so we are doing this in the beforeSave(entity) method.
breeze by design sends the changed entity then back to the client where the cache gets updated with your changes done on the server.

How to initialize and persist Castle ActiveRecordStarter per session for multi tenancy apps?

I am using Castle ActiveRecord in my Asp.net / MVC 2 / Multi-tenancy application with SQL Server as my backend.
For every user logging in, the app loads the corresponding DB, dynamically at run time like below:
IDictionary<string, string> properties = new Dictionary<string, string>();
properties.Add("connection.driver_class", "NHibernate.Driver.SqlClientDriver");
properties.Add("dialect", "NHibernate.Dialect.MsSql2005Dialect");
properties.Add("connection.provider", "NHibernate.Connection.DriverConnectionProvider");
properties.Add("proxyfactory.factory_class", "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");
properties.Add("connection.connection_string", strDBConnection);
InPlaceConfigurationSource source = new InPlaceConfigurationSource();
source.Add(typeof(ActiveRecordBase), properties);
ActiveRecordStarter.Initialize(new System.Reflection.Assembly[] { asm1 }, source);
The strDBConnection string comes from another small database that holds the user info, corresponding DB, etc.
Scenario:
When a user logs in, his DB gets loaded, he can do his CRUD jobs -- No Probs !
Another user logs in (from another remote machine) his DB gets loaded -- No Probs !
Now, when the first user reads from DB, he sees new data from the second user's DB
My little understanding for this behavious is : ActiveRecordStarter is a Static object.
Could someone help me with a solution for this situation ?
The expected behaviour:
each user should access his own DB only, securely, in parallel / at the same time.
Thanks a lot !
ActiveRecordStarter.Initialize should only be called once in your app (in Application_Start in Global.asax).
To achieve what you want, create a class that inherits from NHibernate.Connection.DriverConnectionProvider:
public class MyCustomConnectionProvider : DriverConnectionProvider
{
protected override string GetNamedConnectionString(IDictionary<string, string> settings)
{
return string.Empty;
}
public override IDbConnection GetConnection()
{
// Get your connection here, based on the request
// You can use HttpContext.Current to get information about the current request
var conn = Driver.CreateConnection();
conn.ConnectionString = ... // Retrieve the connection string here;
conn.Open();
return conn;
}
}
Then set the connection.provider property to the name of your class:
properties.Add("connection.provider", "MyCompany.Domain.MyCustomConnectionProvider, MyCompany.AssemblyName");

How to stop WCF data Service to fetch data when SavingChanges (during update)

I am trying to update an entity from a WCF client as follows:
Ctxt.MergeOption = MergeOption.NoTracking;
var q = Ctxt.Customers.Where(p => p.MasterCustomerId == "JEFFERSON").Select(o => o);
//DataServiceCollection<Customer> oCustomers = new DataServiceCollection<Customer>(q, TrackingMode.None);
DataServiceCollection<Customer> oCustomers = new DataServiceCollection<Customer>(q);
oCustomers[0].FirstName = "KEFFERSON";
//Ctxt.SaveChanges(SaveChangesOptions.ReplaceOnUpdate);
//ctxt.SaveChangesDefaultOptions = SaveChangesOptions.ReplaceOnUpdate;
Ctxt.SaveChanges();
When I try to save the modified entity, it first tries to load that entity using a select query (to database) and then issues update statement to database.
In my case, I simply want to have the entity to be directly updated in the database without fetching it first. I don't mind if it overwrites the data in database
I tried the following at WCF service:
protected override EF.Model.DataModel.PersonifyEntities CreateDataSource()
{
var ctxt = new EF.Model.DataModel.PersonifyEntities();
ctxt.Customers.MergeOption = System.Data.Objects.MergeOption.NoTracking;
ctxt.ContextOptions.ProxyCreationEnabled = false;
ctxt.ContextOptions.LazyLoadingEnabled = false;
return ctxt;
}
But, no luck. Can anyone help me on this?
For WCF DataServices, the client can only update entities that it tracks. So it has to have the entity downloaded in the client before it can make any changes and save it back. Thats why you see the fetch (I am assuming that this is the first fetch that you are seeing for that specific entity) before the update. Hope this helps.

Resources