I have a window that looks like so:
Everytime a record is added, I want the repair ID to be set to a unique number that hasn't been used in the table yet. e.g. if there is ID numbers 1,2,3, then when I press +, the ID field should be set to '4'.
Also, if one of the records in the table is deleted, so that the ID numbers are: 1,2,4, then when I press +, the number in the Record ID should be set to 3.
At the moment, I have a custom ManagedObject class, where I declare:
-(void)awakeFromInsert {
[self setValue:[NSDate date] forKey:#"date"];
}
In order to set the date to today's date.
How would I go about implementing this unique record ID?
Thanks!
For a pure autoincrementing ID (like was asked for in this question), something like what's described in this message may do the job. Unfortunately, that won't provide values that fill in the blanks for deleted items in your list.
For small amount of records, simply loop through them until you find a free ID. Pseudocode here since I don't know your language:
int RepairID=1;
While isUsed(RepairID) {
RepairID=RepairID+1;
}
return RepairID;
For large numer of records you can keep track of a list of deleted ID:s and the highest ID. When adding a record pick the smallest deleted ID, or if no deleted ids left to reuse, use the highest ID+1
I've used the numerical form of the date before (with a quick check to make sure it's actually unique - ie, the clock hasn't been adjusted). +[NSDate timeIntervalSinceReferenceDate] returns an NSTimeInterval (which is a typedef double). This I believe is independent of time zones, "daylight saving", etc.
The only weakness, as I alluded earlier, is the clock being adjusted, but you could always make sure it's unique. If you have more requirements than what you listed, let me know. I have a few myself, and what I believe to be sufficient work-arounds.
If your using an Array Controller in your interface you can use the count method on its arrangedObjects array to create your ID. You can implement by overriding your -(id)newObject method
//implemented in yourArrayController.m
-(id)newObject
{
//call the super method to return an object of the entity for the array controller
NSManagedObject* yourNewObject = [super newObject];
//set the ID the count of the arrangedObjects array
NSNumber* theID = [NSNumber numberWithInteger:[[self arrangedObjects] count]];
[yourNewObject setValue:theID forKey:#"ID"];
//return your new Object
return yourNewObject;
}
Related
I have a set of unique items (Index) to each of which are associated various elements of another set of items (in this case, dates).
In real life, if a date is associated with an index, an item associated with that index appeared in a file generated on that date. For combination of dates that actually occurs, I want to know which accounts were present.
let
Source = Table.FromRecords({
[Idx = 0, Dates = {#date(2016,1,1), #date(2016,1,2), #date(2016,1,3)}],
[Idx = 1, Dates = {#date(2016,2,1), #date(2016,2,2), #date(2016,2,3)}],
[Idx = 2, Dates = {#date(2016,1,1), #date(2016,1,2), #date(2016,1,3)}]},
type table [Idx = number, Dates = {date}]),
// Group by
Grouped = Table.Group(Source, {"Dates"}, {{"Idx", each List.Combine({[Idx]}), type {number}}}),
// Clicking on the item in the top left corner generates this code:
Navigation = Grouped{[Dates={...}]}[Dates],
// Which returns this error: "Expression.Error: Value was not specified"
// My own code to reference the same value returns {0,2} as expected.
CorrectValue = Grouped{0}[Idx],
// If I re-make the table as below the above error does not occur.
ReMakeTable = Table.FromColumns(Table.ToColumns(Grouped), Table.ColumnNames(Grouped))
in ReMakeTable
It seems that I can use the results of this in my later work even without the Re-make (I just can't preview cells correctly), but I'd like to know if what's going on that causes the error and the odd code at the Navigation step, and why it disappears after the ReMakeTable step.
This happens because when you double click an item, the auto-generated code uses value filter instead of row index that you are using to get the single row from the table. And since you have a list as a value, it should be used instead of {...}. Probably UI isn't capable to work with lists in such a situation, and it inserts {...}, and this is indeed an incorrect value.
Thus, this line of code should look like:
Navigate = Grouped{[Dates = {#date(2016,1,1), #date(2016,1,2), #date(2016,1,3)}]}[Idx],
Then it will use value filter.
This is a bug in the UI. The index the UI calculates is incorrect: it should be 0 instead of [Dates={...}]. ... is a placeholder value, and it generates the "Value was not specified" exception if it is not replaced.
I am currently experiencing some issues regarding table view sorting from firebase. What I am trying to achieve is to list 5 different price tiers in a table view, all named (tier1, tier5, tier12, tier24, tierPermanent) - each containing a value (the price).
However, while fetching these values from the database, I find it rather difficult to show these in a table view - both containing text (the time) and the price tiers. What I am doing now, is that I am using observeEventType to display all the values, and then store each value in a dictionary. After that I append it to an array of dictionaries of type [[String:String]].
What I am struggling with, is to display this in a descending order in a table view. Please take note that all of these 5 values are optional, and therefore they might not contain any value - so instead of showing a value on the very first row, and a blank cell at the second, and then a new value on the third row - I want it to display descending compared to the values. (The permanent value will always be on top if it contains a value, or else tier24 will be on top, or else tier12.). For each cell.
I know I would access the unique value with cell.nameLabel.text = cell[indexPath.row]["tier.."] as? String - but the problem is that I need to have some sort of ordering, and make sure the data isn't displayed twice. (order with both key and value - to display both key and value in the same cell.).
Any ideas on how I would approach this?
Thanks in advance.
There's really not enough data to fully address the question but how about this:
A Firebase structure:
tiers
-Y0998uas9j
tier_type: tier_24
time: 20160705130100
sort_order: 1
-Ykja9s9js9
tier_type: tier_05
time: 20160705130300
sort_order: 3
-Yukl9jh8sj
tier_type: tier_permanent
time: 20160705130500
sort_order: 0
tiers have a sort order to keep them in the correct order.
tier_permanent = 0
tier_24 = 1
tier_12 = 2
tier_05 = 3
tier_01 = 4
and some code to read them in and keep the sorted, descending:
var myArray = [[String:String]]()
let tiersRef = self.myRootRef.child("tiers")
tiersRef.observeSingleEventOfType(.Value, withBlock: { snapshot in
for child in snapshot.children {
var dict = [String: String]()
dict["fbKey"] = child.key as String
dict["tier_type"] = child.value["tier_type"] as? String
dict["timestam"] = child.value["time"] as? String
dict["sort_order"] = child.value["sort_order"] as? String
myArray.append(dict)
}
myArray.sortInPlace( {$0["sort_order"] < $1["sort_order"]} )
self.mySuperTableView.reloadData()
for dict in myArray { //meh, print them so show they are sorted
print(dict)
}
})
This addresses: keeping them sorted, descending, and if the tires are not present in the database, they will obviously not be read in.
The issue is though, it's unclear from he question the correlation between the tier names and the value (time?). I'll update once more information has been presented.
Is there an efficient way to delete multiple rows in HBase or does my use case smell like not suitable for HBase?
There is a table say 'chart', which contains items that are in charts. Row keys are in the following format:
chart|date_reversed|ranked_attribute_value_reversed|content_id
Sometimes I want to regenerate chart for a given date, so I want to delete all rows starting from 'chart|date_reversed_1' till 'chart|date_reversed_2'. Is there a better way than to issue a Delete for each row found by a Scan? All the rows to be deleted are going to be close to each other.
I need to delete the rows, because I don't want one item (one content_id) to have multiple entries which it will have if its ranked_attribute_value had been changed (its change is the reason why chart needs to be regenerated).
Being a HBase beginner, so perhaps I might be misusing rows for something that columns would be better -- if you have a design suggestions, cool! Or, maybe the charts are better generated in a file (e.g. no HBase for output)? I'm using MapReduce.
Firstly, coming to the point of range delete there is no range delete yet in HBase, AFAIK. But there is a way to delete more than one rows at a time in the HTableInterface API. For this simply form a Delete object with row keys from scan and put them in a List and use the API, done! To make scan faster do not include any column family in the scan result as all you need is the row key for deleting whole rows.
Secondly, about the design. First my understanding of the requirement is, there are contents with content id and each content has charts generated against them and those data are stored; there can be multiple charts per content via dates and depends on the rank. In addition we want the last generated content's chart to show at the top of the table.
For my assumption of the requirement I would suggest using three tables - auto_id, content_charts and generated_order. The row key for content_charts would be its content id and the row key for generated_order would be a long, which would auto-decremented using HTableInterface API. For decrementing use '-1' as the amount to offset and initialize the value Long.MAX_VALUE in the auto_id table at the first start up of the app or manually. So now if you want to delete the chart data simply clean the column family using delete and then put back the new data and then make put in the generated_order table. This way the latest insertion will also be at the top in the latest insertion table which will hold the content id as a cell value. If you want to ensure generated_order has only one entry per content save the generated_order id first and take the value and save it into content_charts when putting and before deleting the column family first delete the row from generated_order. This way you could lookup and charts for a content using 2 gets at max and no scan required for the charts.
I hope this is helpful.
You can use the BulkDeleteProtocol which uses a Scan that defines the relevant range (start row, end row, filters).
See here
I ran into your situation and this is my code to implement what you want
Scan scan = new Scan();
scan.addFamily("Family");
scan.setStartRow(structuredKeyMaker.key(starDate));
scan.setStopRow(structuredKeyMaker.key(endDate + 1));
try {
ResultScanner scanner = table.getScanner(scan);
Iterator<Entity> cdrIterator = new EntityIteratorWrapper(scanner.iterator(), EntityMapper.create(); // this is a simple iterator that maps rows to exact entity of mine, not so important !
List<Delete> deletes = new ArrayList<Delete>();
int bufferSize = 10000000; // this is needed so I don't run out of memory as I have a huge amount of data ! so this is a simple in memory buffer
int counter = 0;
while (entityIterator.hasNext()) {
if (counter < bufferSize) {
// key maker is used to extract key as byte[] from my entity
deletes.add(new Delete(KeyMaker.key(entityIterator.next())));
counter++;
} else {
table.delete(deletes);
deletes.clear();
counter = 0;
}
}
if (deletes.size() > 0) {
table.delete(deletes);
deletes.clear();
}
} catch (IOException e) {
e.printStackTrace();
}
Greetings,
The context is myFaces 2.0.2, possibly also adding Tomahawk 20-1.1.10
I have created a dataTable (currently an h:dataTable, but could also be a t:dataTable using Tomahawk) displaying certain attibutes of a List<MyObject> in a backing bean. I have paging by returning only a subList of the List, and also sorting by click of column headers.
The next thing I need to do is ensure the table always shows a fixed number of rows. For example, if my page size is 5 and I have 12 items in the List, I need page three to show the last two items, plus 3 blank rows.
I have tried to "pad" the subList with both nulls and instances of myObject with null values, but this led to ConcurrentModificationException when hitting the last page of the table (the view was trying to getDisplayList even as the paging method was still adding the extra values.). I then tried padding the main list in the same manner, but then got NullPointers on my sort functions (a no-brainer in hind sight). Plus, these things are all addng overhead in the backer, when I would rather do this in the xhtml view.
(h:/t:)dataTable does have a rows attribute, but this specifies the maximum number of rows to display, not the minimum, as I need.
Ideas, please?
Don't pad the sublist. Pad the list. Preferably immediately after retrieving it in the bean.
The solution here was to pad the MAIN List, rather than the subList, using objects which are not null but whose attributes are null, and to add a null check into the Comparator:
if (obj1.getSomeValue() == null) {
return +1;
}
else if (obj2.getSomeValue() == null) {
return -1;
}
else {
// primary sorting code
}
Which ensures null items always come last. Works perfect.
BalusC did give me the push in the right direction, so I am accepting his answer.
I wanted to change the grid column sequence dynamically. For e.g. By default the grid will be loaded in LoginId, FirstName and LastName sequence. Based on some condition, I need to change the FirstName and LastName sequence.
Is there any way I can do this?
I tried doing like:
{name:'UserName',index:'UserName',width:82,sortable:false},
if(true)
{
{name:'FirstName',index:'FirstName',width:65,sortable:false},
{name:'LastName',index:'LastName',width:65,sortable:false},
}
else
{
{name:'LastName',index:'LastName',width:65,sortable:false},
{name:'FirstName',index:'FirstName',width:65,sortable:false},
}
but I could not get this work.
You can use remapColumns function to do this. In the documentation of the function you will find the example which seems to be wrong, because indexes in the permutation array seem to be 1-based and not 0-based. Try to use:
$("#list").remapColumns([1,3,2],true,false);
or
$("#list").remapColumns([1,3,2,4,5,6,7,8,9],true,false);
if you want to change the order of the second and third from the total 9 columns.