Cannot update item where two columns combination must be unique - angularjs

I am making an application with azure mobile services which stores users hours and points in a table called attended users. The problem I have is when I try and update the one specific user it selects all of the users with the same club id. I need an update function that finds a user with a club id and UniqueUserID that are unique, then updates the hours and points based on the one result.
Controller Code
$scope.saveChanges = function(){
$scope.show($ionicLoading);
var query = client.getTable('AttendedClubs').update({id: clubID.getJson(), UniqueUserID: memberID.getJson(), Hours: $scope.profile.Hours, Points: $scope.profile.Points}).done(function(results) {
$scope.hide($ionicLoading);
}, function(error) {
$scope.hide($ionicLoading);
alertDialogue.pop("No Internet Connection","Check Connection");
});
}

You are using a unique ID of the clubID. You need to construct this. When you create your object, do something like:
var table = client.getTable('AttendedClubs');
table.insert({
id: uuid.v4(),
clubID: clubID.getJson(),
UniqueUserID: memberID
...
});
To update all records, first do a fetch, then do an update on a per-record basis. Use the id to uniquely identify the record.

Related

What's wrong this this DynamoDb query "Query condition missed key schema element"

I'm hoping this is something really simple that I've miss understood as I'm new to both DynamoDb and nodeJs.
I have a table that has id, siteId.
These are being used to create a Global Secondary Index named IdxSiteId.
I need to be able to grab some of the other Item's values (not shown in screenshot) using the siteId. Reading things the best option is to use Query rather than GetItemBatch or Scan. Through trail and error got to this point.
const getWarnings = async (siteId) => {
const params = {
TableName: process.env.WARNINGS_TABLE_NAME,
IndexName: 'IdxSiteId',
KeyConditionExpression: 'SiteId = :var_siteId',
ExpressionAttributeValues: {
':var_siteId': siteId
},
ProjectionExpression: 'id, endTime, startTime, warningSubType',
ScanIndexForward: false
};
return new DynamoDB.DocumentClient().query(params).promise();
};
While this is the closest it has appeared to working I'm getting the following error Error retrieving current warnings ValidationException: Query condition missed key schema element: siteId and looking at the examples online I don't know what I'm doing wrong at this point.
As I said I'm sure this is super simple, but I could really do with a pointer.
Field names are case sensitive. Your GSI partition key is siteId. Your query is SiteId = :var_siteId. It should be siteId = :var_siteId.

How should DB entity IDs be managed to avoid security risks in a performant way?

Let's suppose I have a small website where users can public book reviews. So, in the server code we have somewhere something like this:
// Get user's read books.
public IHttpActionResult GetBooks()
{
var user = GetLoggedUser();
var userBooks = BooksRepository.GetByUserId(user.Id);
return Ok({
Name: user.Name,
Books: userBooks.ToDtoList()
});
}
public IHttpActionResult GetReviews(int bookId)
{
var reviews = ReviewsRepository.GetByBookId(bookId);
return Ok({
Reviews: reviews.ToDtoList()
});
}
Among other things, the review objects have an ID property (integer), that's their ID in the database. Now let's suppose I'm a malicious user, I log in and then, I start doing something like:
let limit = 100;
for (let id = someStart; id < (someStart + limit); id++) {
fetch(URL + '/reviews?bookId=' + id)
.then( /* getting other users' reviews... */ );
}
In order to avoid that situation, instead of using integers, I have seen people using GUIDs as the primary key of their tables. Do databases order GUIDs somehow internally so they can create an index? If not, isn't it a slow approach? Is there a better way to deal with IDs sent to the browser?
Yes, there is a better way. Keep your integer IDs internal and never expose them to the clients.
One thing I did in the past, several times even, is to add a GUID column while keeping the original int IDs. Your back-end can still function using the int IDs, but when it comes to exposing data to the client, at that point you only send the GUIDs and never make the int IDs public. If a request is made from the browser, it will come with the GUID at which point you can obtain the int ID if you need it for something.
So, you're not changing your primary keys, all you do is add a new GUID column and then expose that to the clients.

Is there a built-in function to get all unique values in an array field, across all records?

My schema looks like this:
var ArticleSchema = new Schema({
...
category: [{
type: String,
default: ['general']
}],
...
});
I want to parse through all records and find all unique values for this field across all records. This will be sent to the front-end via being called by service for look-ahead search on tagging articles.
We can iterate through every single record and run go through each array value and do a check, but this would be O(n2).
Is there an existing function or another way that has better performance?
You can use the distinct function to get the unique values across all category array fields of all documents:
Article.distinct('category', function(err, categories) {
// categories is an array of the unique category values
});
Put an index on category for best performance.

Different objects for saving and displaying?

I have an invoice object that has an account object inside it. When displaying the invoice to a user, I have the following object:
invoice : {
Number : 1234,
Account : { id: 12345,
name: "Test account"
}
}
When saving an invoice, the user can select the account from a drop down. In that case, all I really need is the id of that account so my object will look something like this:
invoice : {
Number : 1234,
AccountId : 12345
}
My question is: Do I need to create two different objects one for saving and another one for displaying the invoice? If not, how would you handle this?
Thanks!!
Create another property "AccountId" in same javascript object and delete unwanted property just before saving it.
invoice.AccountId = invoice.Account.id;
delete invoice['Account'];

What is the preferred way to set foreign relationships for an entity?

Product product = new Product() {
Category = category
};
_session.CommitChanges();
vs.
Product product = new Product() {
Category.ID = category.ID
};
_session.CommitChanges();
What is the difference? Which one to use? Both seem to be valid and get correctly saved in the database.
Always use the first version. This will make sure all the relations are in a state they should be , because the keys and stuff are assigned and managed by the RelationshipManager.
I just pass Category.ID.
When the query is executed against the database the only information that is passed to Product is the Category ID, that is, this is the info that will be stored in DB (in each Product row).
Behind the curtains, the engine knows the fields necessary to generate the SQL insert command, in this case, only Category.ID is necessary when saving the Product. That's why no matter what option you choose, the save operation always succeeds.

Resources