I'm new to Sinatra and I want to create a service for a mobile application. I've created a small project that records entries into the datamapper, and am able to extract all the information and return a json object. The problem is, is that as you add in more data to the database the response will get larger and will take a while to download on a mobile device. So I would like to extract the data in a different way, by giving it the Serial id, I would like to only extract the next 10 entries based on completed_at time (see below).
class NewsObject
include DataMapper::Resource
property :id, Serial
property :title, String
property :completed_at, DateTime, :default => DateTime.now
end
So far I'm manged to extract the information in the correct order and limit the response (see below), I just need to figure out how to start at a certain Serial id
NewsObject.all(:order => [:completed_at], :limit => 2)
Have you tried this?
NewsObject.all(:order => [:completed_at], :limit => 2, :id.gte => my_id)
Related
I'm trying to set up a webpage that communicates with a Moodle page. I need different data from a database activity and want to create new entries. Note that I am not talking about the SQL database in BG, it is the activity database in courses.
The information should be retrieved/transferred via the REST API, an HTML POST Request. My problem is that I don't know how to add a new record to the database activity because I cannot transfer the data array. Only the first parameter given appears in my database.
E.g. i tried ...&wsfunction=mod_data_add_entry&databaseid=10&data[0][fieldid]=66&data[0][value]=12&data[1][fieldid]=67&data[1][value]=test
And many other combinations. Always only the first parameter is shown in the database.
The docs tell me this (Pseudocode):
//The fields data to be created
list of (
object {
fieldid int //The field id.
subfield string Default to "" //The subfield name (if required).
value string //The contents for the field always JSON encoded.
}
)
Alternatively:
REST (POST parameters)
data[0][fieldid]= int
data[0][subfield]= string
data[0][value]= string
I cannot find anywhere else something called a "subfield".
Any ideas?
Okay, found it. You have to put your values in "", unless they are not a number. Seems like there is a connection with this special activity because you don't have to do it elsewhere.
I need numeric IDs for human readability. How do I get it in Firebase?
I want numeric ID for keys, e.g. "000000001", "000000002","00000003","00000004".
The reason I need it is because these IDs will become the permanent object ID both online and offline. I want users to be able to browse that object page by just entering URL "/objects/00000001" without efforts.
I am asking here, because I want to know if this can be done without using .priority, sub-properties, etc. I guess set method can do it somehow. If it is not possible, just tell me no, I can accept that answer.
I'd suggest reading through the Firebase documentation. Specifically, see the Saving Data portion of the Firebase JavaScript Web Guide.
From the guide:
Getting the Unique ID Generated by push()
Calling push() will return a reference to the new data path, which you can use to get the value of its ID or set data to it. The following code will result in the same data as the above example, but now we'll have access to the unique push ID that was generated
// Generate a reference to a new location and add some data using push()
var newPostRef = postsRef.push({
author: "gracehop",
title: "Announcing COBOL, a New Programming Language"
});
// Get the unique ID generated by push() by accessing its key
var postID = newPostRef.key;
Source: https://firebase.google.com/docs/database/admin/save-data#section-ways-to-save
A push generates a new data path, with a server timestamp as its key. These keys look like -JiGh_31GA20JabpZBfa, so not numeric.
If you wanted to make a numeric only ID, you would make that a parameter of the object to avoid overwriting the generated key.
The keys (the paths of the new data) are guaranteed to be unique, so there's no point in overwriting them with a numeric key.
You can instead set the numeric ID as a child of the object.
You can then query objects by that ID child using Firebase Queries.
From the guide:
In JavaScript, the pattern of calling push() and then immediately calling set() is so common that we let you combine them by just passing the data to be set directly to push() as follows. Both of the following write operations will result in the same data being saved to Firebase:
// These two methods are equivalent:
postsRef.push().set({
author: "gracehop",
title: "Announcing COBOL, a New Programming Language"
});
postsRef.push({
author: "gracehop",
title: "Announcing COBOL, a New Programming Language"
});
Source: https://firebase.google.com/docs/database/admin/save-data#getting-the-unique-key-generated-by-push
As explained above, you can use the Firebase default push id.
If you want something numeric you can do something based on the timestamp to avoid collisions
f.e. something based on date,hour,second,ms, and some random int at the end
01612061353136799031
Which translates to:
016-12-06 13:53:13:679 9031
It all depends on the precision you need (social security numbers do the same with some random characters at the end of the date). Like how many transactions will be expected during the day, hour or second. You may want to lower precision to favor ease of typing.
You can also do a transaction that increments the number id, and on success you will have a unique consecutive number for that user. These can be done on the client or server side.
(https://firebase.google.com/docs/database/android/read-and-write)
Adding to the #htafoya answer.
The code snippet will be
const getTimeEpoch = () => {
return new Date().getTime().toString();
}
As the docs say, this can be achieved just by using set instead if push.
As the docs say, it is not recommended (due to possible overwrite by other user at the "same" time).
But in some cases it's helpful to have control over the feed's content including keys.
As an example of webapp in js, 193 being your id generated elsewhere, simply:
firebase.initializeApp(firebaseConfig);
var data={
"name":"Prague"
};
firebase.database().ref().child('areas').child("193").set(data);
This will overwrite any area labeled 193 or create one if it's not existing yet.
https://firebase.google.com/docs/firestore/manage-data/transactions
Use transactions and keep a number in the database somewhere that you can increase by one. This way you can get a nice numeric and simple id.
I'm using Drupal 7, with the Views, Feeds and Views PHP modules (among others, but I think those are the only relevant ones).
My goal is a single view that combines (a) multiple RSS feeds brought in through the Feeds module, (b) two or three content types of my own, for contant created manually on my site. The result will be a block and a page that has a stream of all my latest work, wherever it is -- my own site or another site (as long as that other site has an RSS feed, of course).
The ideal result would show a single list, sorted by date, mingling the items without regard for content type.
My problem: The Feeds module and my custom content types have different date fields. My content types have a field called Original Date, which I set when I create content (eg, adding an article I wrote three years ago -- I clearly want it to be sorted by when it was published, not when I added it to the site). However, each feed_item has a date field, Published Date, that corresponds to the date in the RSS feed and is received with the rest of the item by RSS.
I have tried to use the Views PHP functionality to use if/then statements, in a variety of ways. For example, I check what the content_type is, and then set a variable to either the Original Date or by the Published Date, depending on the content type. Alternatively, I have tested whether the Original Date field is set; if so, I return that field, otherwise I return the Published Date field. They all fail in various ways. Most throw PHP errors that are visible even to anonymous users (obviously a problem).
I have tried these various approaches directly in the Sort Criterial section of Views; I've also tried to come up with the date in the Fields section, and then have a Sort criterion call that result. I've converted everything to a Unix timestamp, to make sure I have something simple to sort by; I've tried leaving dates as dates. No luck any which way.
Here's the really weird part: I have successfully used these approaches to display the correct date, so that (for example) the block shows • TITLE | Original Date for custom content types, and • TITLE | Published Date for feed items. But when I try the same approach(es) to sort by date, it fails.
Am I overlooking something simpler? Do I have to use PHP Views? Is there some other way to sort a View of multiple content types by a combination of two different (though similar) fields?
Thanks!
tf
Have you tried using the relationship feature of views? You could use that to get access to all of the date fields of all of the content types, then add some conditional code to the field item and you should be golden. (That is, if I'm understanding the question correctly...)
I found many possible solutions and summarized them here: https://drupal.org/node/2133879
However, this is a simple solution that I'd recommend:
In a custom module use the hook_views_query_alter() function to alter the sort criteria to use CASE ... WHEN to add a conditional in the orderby condition. A good example is shown here:
<?php
/**
* Implements hook_views_query_alter
* #param type $view
* #param type $query
*/
function MODULE_views_query_alter(&$view, &$query) {
if ($view->name == 'views_name' && $view->current_display == 'display_name') {
$query->orderby = array(
array(
'field' => 'CASE WHEN field_data_field_date_publication.field_date_publication_value
THEN field_data_field_date_publication.field_date_publication_value
ELSE node.created END',
'direction' => 'DESC',
)
);
}
}
?>
I'm new to reporting services so this question might be insane. I am looking for a way to create an empty 'template' report (that is basically a form letter) rather than having to create one for every client in our system. Part of this form letter is a section that has any number of 25 specific fields. The section is arranged as such:
Name: Jesse James
Date of Birth: 1/1/1800
Address: 123 Blah Blah Street
Anywhere, USA 12345
Another Field: Data
Another Field2: More Data
Those (and any of the other fields the client specifies) could be arranged in any order and the label on the left could be whatever the client decides (example: 'DOB' instead of 'Date of Birth'). IDEALLY, I'd like to be able to have a web interface where you can click on the fields you want, specify the order in which they'll appear, and specify what the custom label is. I figured out a way to specify the labels and order them (and load them 'dynamically' in the report) but I wanted to take it one step further if I could and allow dynamic field (right side) selection and ordering. The catch is, I want to do this without using dynamic SQL. I went down the path of having a configuration table that contained an ordinal, custom label text, and the actual column name and attempting to join that table with the table that actually contains the data via information_schema.columns. Maybe querying ALL of the potential fields and having an INNER JOIN do my filtering (if there's a match from the 'configuration' table, etc). That doesn't work like I thought it would :) I guess I was thinking I could simulate the functionality of a dataset (it having the value and field name baked in to the object). I realize that this isn't the optimal tool to be attempting such a feat, it's just what I'm forced to work with.
The configuration table would hold the configuration for many customers/reports and I would be filtering by a customer ID. The config table would look somthing like this:
CustID LabelText ColumnName Ordinal
1 First Name FName 1
1 Last Name LName 2
1 Date of Birth DOBirth 3
2 Client ID ClientID 1
2 Last Name LName 2
2 Address 1 Address1 3
2 Address 2 Address2 4
All that to say:
Is there a way to pull off the above mentioned query?
Am I being too picky about not using dynamic SQL as the section in question will only be pulling back one row? However, there are hundreds of clients running this report (letter) two or three times a day.
Also, keep in mind I am not trying to dynamically create text boxes on the report. I will either just concatenate the fields into a single string and dump that into a text box or I'll have multiple reports each with a set number of text boxes expecting a generic field name ("field1",etc). The more I type, the crazier this sounds...
If there isn't a way to do this I'll likely finagle something in custom code; but my OCD side wants to believe there is SQL beyond my current powers that can do this in a slicker way.
Not sure why you need this all returned in one row: it seems like SSRS would want this normalized further: return a row for every row in the configuration table for the current report. If you really need to concatenate then do that in Embedded code in the report, or consider just putting a table in the form letter. The query below makes some assumptions about your configuration table. Does it only hold the cofiguration for the current report, or does it hold the config for many customers/reports at once? Also you didn't give much info about how you'll filter to the appropriate record, so I just used a customer ID.
SELECT
config.ordinal,
config.LabelText,
CASE config.ColumnName
WHEN 'FName' THEN DataRecord.FirstName
WHEN 'LName' THEN DataRecord.LastName
WHEN 'ClientID' THEN DataRecord.ClientID
WHEN 'DOBirth' THEN DataRecord.DOB
WHEN 'Address' THEN DataRecord.Address
WHEN 'Field' THEN DataRecord.Field
WHEN 'Field2' THEN DataRecord.Field2
ELSE
NULL
END AS response
FROM
ConfigurationTable AS config
LEFT OUTER JOIN
DataTable AS DataRecord
ON config.CustID = DataRecord.CustomerID
WHERE DataRecord.CustomerID = #CustID
ORDER BY
config.Ordinal
There are other ways to do this, in SSRS or in SQL, depends on more details of your requirements.
In many of my apps, it requires associating some data with a contact in addressbook. What I used to do is save the record id of an ABPerson and use that id to pull information upon each app launch. However, more and more I find that this approach is wrong because many times a user will use a service like mobileme where the addressbook is wiped and resynced. This causes the record id to change and all associations are lost. The user will have to go through each one and re-link them.
What is a better approach to holding a robust pointer to addressbook entries?
You should store three values: the record ID, the first name, and the last name.
1) In the case that the record ID hasn't changed, you're golden - just use that to locate the proper record.
2) If ABAddressBookGetPersonWithRecordID() does not locate a record for your stored record ID (it returns NULL), then you'll need to search the person records for a match based on the first and last name. You can drop down to using ABAddressBookCopyPeopleWithName() potentially or write your own locating code if you already have an array with all the person records in-memory. Locating the new record is up to you. Once to locate the new record, you can update your data storage with the new record ID.
Ultimately, you end up storing the record ID to use directly incase it doesn't change (if you're lucky) plus storing some keys from the address book entry that are unlikely to change. The name of the person or organization associated with an address book entry is most likely to change. You should, of course, account for the case where you may not find a record with the stored record ID or by searching for the name. This could trivially mean that the record was deleted, or it could mean that the record was renamed. You should handle that case whichever way you decide is best for your specific application.
I know this was last year, however, I thought I might suggest a method I use. The first time I ask the user to pick a contact (in order to associate certain of my app's private data with it) I then grab the record, create my own internal record id (the initials of the app name and a sequence number usually) modify the contact by adding a new ABRelatedName (type of "pref" name of "Other") value of my own internal record id. It looks like this in the .vcf
item3.X-ABRELATEDNAMES;type=pref:BZA101
item3.X-ABLabel:_$!<Other>!$_
That way, I can simply reference that record id when i add more data about the user such as the last time the app user contacted them, etc. Seems to work for me.
Hope that helps someone.
If the address book is indeed being completely wiped and re-loaded, and the only part that doesn't change is the display name, then storing the display name as the link seems like the only option.