[gecode-users] assert in propagator cast
David Rijsman
David.Rijsman at quintiq.com
Fri Nov 4 14:53:51 CET 2011
Hi Christian,
in my case the dispose of the advisor is the one that cancels the subscription to the variable. The dispose of the propagator is the one that disposes the council (and the council disposes the advisors still in the council). So I think I dispose (and cancel) enough. The assert was raised when I only disposed 4 (any subset) out of 5 of the advisors related to a task for which the boolean turned false. I fixed this to 5 and the problem no longer happens. I just can not figure out why the assert was raised especially it should not hurt to wait with disposing of an individual advisor until the council disposes. I will keep searching and post when I find something,
David Rijsman
>>>
From: "Christian Schulte" <cschulte at kth.se>
To: "'David Rijsman'" <David.Rijsman at quintiq.com>, <users at gecode.org>
Date: 11/4/2011 12:50 PM
Subject: RE: [gecode-users] assert in propagator cast
Hi David,
Ok, let's see: when the Boolean variable becomes assigned you dispose the
advisors. But do you also cancel the subscriptions?
As you correctly observed, some advisors have a dispose function that also
does the cancel. If an advisor has a dispose function that does not cancel,
then the cancel has to be done manually.
For assigned views, subscriptions do not need to be cancelled but advisors
still must be disposed. You might do that in the advise() function or in the
dispose() function but have to be careful to only do it once!
Please let me know whether this helps.
Best
Christian
--
Christian Schulte, www.ict.kth.se/~cschulte/
-----Original Message-----
From: users-bounces at gecode.org [mailto:users-bounces at gecode.org] On Behalf
Of David Rijsman
Sent: Friday, November 04, 2011 11:44 AM
To: users at gecode.org; cschulte at kth.se
Subject: Re: [gecode-users] assert in propagator cast
Hi Christian,
a little bit delayed but yes you are pretty close with your guessing. I do
step 1 and step 2 I do cancel the subscription. Also in the dispose method
of the propagator I invoke the dispose method of the council.
Should I also cancel all the subscriptions of the variables to the advisors
in the propagators dispose although I invoke the dispose on the council? I
checked the dispose of the council and it also invokes the dispose of the
advisors which in my case do cancel the subscriptions.
In the example in gecode/int/bool/or.hpp you are using the advisor type
Advisor in which the cancellation does not take place (in my case it does in
the specialized implementation of dispose) so I understand the need to
explicitly do it in the dispose of the propagator in your case. But I do not
see it in my case....
To give you a little more background, I have a propagator working on tasks,
each task has five variables of which one is a boolean. When the boolean
becomes false I want to dispose all the advisors on all the five variables
associated with this task. When the boolean becomes false, in the advise of
the propagator I iterate over all the advisors in the council, cast them to
my advisor type, ask the advisor if it belongs to the same task as the
boolean, if so it is disposed. I had made an optimization which would stop
iterating over the advisors once it disposed four, this is a mistake as it
could have found the advisor of the boolean itself and dispose it, now if I
exclude the explicit disposal of the advisor of the boolean variable the
problem no longer occurs. I am a little puzzled here how this is related to
the assert being raised (a double disposal also raises an assert and I do
not see this), I will continue my search but if you have any suggestions
that would be great,
Another question for my understanding, who is (responsible for) disposing
the advisor when a variable becomes assigned?
thanks,
David Rijsman
>>>
From: "Christian Schulte" <cschulte at kth.se>
To: "'David Rijsman'" <David.Rijsman at quintiq.com>, <users at gecode.org>
Date: 10/25/2011 5:48 PM
Subject: Re: [gecode-users] assert in propagator cast
Hi David,
Let me do some guessing here:
1) You are using a propagator that uses advisors.
2) The dispose method of your advisors does not unsubscribe the advisor from
the view.
3) The propagator's dispose method disposes the advisors' council without
deleting the advisors subscriptions
Bang! Is that correct?
If yes, there are two ways to fix it:
a) The dispose method of the advisors also unsubscribes, or
b) In the propagator's dispose method you iterate over all advisors and
unsubscribe (The iterator is called Advisors<A> where A is the type of the
advisor). You might want to search for Advisors in gecode/int/bool/or.hpp
for an example.
I hope that helps!
Best
Christian
PS: Sorry for the delay, I was travelling.
--
Christian Schulte, KTH, web.it.kth.se/~cschulte/
-----Original Message-----
From: users-bounces at gecode.org [mailto:users-bounces at gecode.org] On Behalf
Of David Rijsman
Sent: Monday, October 24, 2011 3:34 PM
To: users at gecode.org
Subject: [gecode-users] assert in propagator cast
I need some help with an assert being thrown by Gecode, hopefully by an
error I made in a propagator I have created. Is there an obvious candidate
for an error I made in my propagator when this assert is thrown?
The assert is thrown in core.hpp
forceinline Propagator&
Advisor::propagator(void) const {
assert(!disposed());
return *Propagator::cast(ActorLink::prev());
}
as a result of an invocation of Advisor::cast(*a)->propagator().afc() in:
template<class VIC>
forceinline double
VarImp<VIC>::afc(void) const {
if (degree() == 0)
return 0.0;
double d = degree();
// Count the afc of each propagator
{
ActorLink** a = const_cast<VarImp<VIC>*>(this)->actor(0);
ActorLink** e =
const_cast<VarImp<VIC>*>(this)->actorNonZero(pc_max+1);
while (a < e) {
d += Propagator::cast(*a)->afc(); a++;
}
}
// Count the afc of each advisor's propagator
{
ActorLink** a =
const_cast<VarImp<VIC>*>(this)->actorNonZero(pc_max+1);
ActorLink** e = const_cast<VarImp<VIC>*>(this)->base+entries;
while (a < e) {
d += Advisor::cast(*a)->propagator().afc(); a++;
}
}
return d;
}
thanks,
David Rijsman
_______________________________________________
Gecode users mailing list
users at gecode.org
https://www.gecode.org/mailman/listinfo/gecode-users
_______________________________________________
Gecode users mailing list
users at gecode.org
https://www.gecode.org/mailman/listinfo/gecode-users
_______________________________________________
Gecode users mailing list
users at gecode.org
https://www.gecode.org/mailman/listinfo/gecode-users
More information about the users
mailing list


|
CALYPSO
Criteria Assessment Logic for Your
Population Studies of Observations |
Feasibility Study List | Help |
| CALYPSO is in READ-ONLY mode | |
|
Description
|
| Index Cohort ID: | Matching Cohort ID: |
|
Inclusion Rules new
|
Please select an inclusion rule to edit.
|


---
layout: talk_reveal3
title: Nextstrain Workshop
venue: CDC
event: AMD Training
author: Trevor Bedford
---
{{ page.title }}
Trevor Bedford (@trvrb)
{{ page.date | date: "%-d %b %Y" }}
{{ page.event }}
{{ page.venue }}
Sequencing to reconstruct pathogen spread
Epidemic process
Sample some individuals
Sequence and determine phylogeny
Sequence and determine phylogeny
Pathogen genomes may reveal:
- Evolution of new adaptive variants
- Epidemic origins
- Patterns of geographic spread
- Animal-to-human spillover
- Transmission chains
Influenza: Forecasting spread of new variants for vaccine strain selection
Zika: Uncovering origins of the epidemic in the Americas
Ebola: Revealing spatial spread and persistence in West Africa
MERS: Quantifying camel-to-human spillover
TB: Tracking individual transmission chains
Genomic analyses are mostly done in a retrospective manner
Dudas and Rambaut 2016
Key challenges to making genomic epidemiology actionable
- Timely analysis and sharing of results critical
- Dissemination must be scalable
- Integrate many data sources
- Results must be easily interpretable and queryable
Nextstrain is two things
- a bioinformatics toolkit and visualization app, which can be used for a broad range of datasets
- a collection of real-time pathogen analyses kept up-to-date on the website nextstrain.org
Nextstrain architecture
All code open source at github.com/nextstrain
Two central aims: (1) rapid and flexible phylodynamic analysis and
(2) interactive visualization
Rethink database of virus and titer data
- Harmonizes data from different sources
- Integrates different types of data (serology, sequences, case details)
- Provides an interface for downstream analysis
Build scripts to align sequences, build trees and annotate
- Flexible build scripts to incorporate different viruses and analyses
- Constructs time-resolved phylogenies
- Annotates with geographic transitions and mutation events
Example augur pipeline for 1600 Ebola genomes
- Align with MAFFT (34 min)
- Build ML tree with RAxML (54 min)
- Temporally resolve tree and geographic ancestry with TreeTime (16 min)
- Total pipeline (1 hr 46 min)
Pipeline consists of Unix-like command line modules
- Modules called via
augur filter
, augur tree
, augur traits
, etc...
- Designed to be composable across pathogen builds
- Uses Snakemake to define a pipeline, making steps obvious
- Provides depedency graph for fast recomputation
- Pathogen-specific repos give users an obvious foundation to build off of
Web visualization of resulting trees
- Interactive data exploration and filtering
- Framework through React / D3
- Connects phylogeny, geography and genotypes
Todays' workshop
- Brief background on phylodynamics
- Focus of running augur and constructing snakefiles
- Running auspice
Phylogeny describes evolutionary relationships
Phylogeny is usually a hypothesis based on characteristics of sampled taxa
Phylogeny implies a series of mutational events leading to observed tip states
"Data" is generally a sequence alignment
Phylogeny structures site patterns
Tree space is vast
There are (2n-3)!! rooted trees for n taxa
- 3 taxa: 3 trees
- 5 taxa: 105 trees
- 10 taxa: 34,459,425 trees
- 20 taxa: 8.2 × 1021 trees
- 50 taxa: 2.8 × 1076 trees
- 100 taxa: 3.3 × 10184 trees
Solution space is rugged
Types of phylogenetic inference methods
- Distance-based (neighbor-joining, fast, heuristic)
- Parsimony (fast, "model-free")
- Maximum likelihood (infers model of mutation, accurate, examples: FastTree, RAxML)
- Bayesian (like ML, but requires prior, produces estimates of uncertainty, examples: MrBayes, BEAST)
Inference is a tree topology, branch lengths and ancestral states
Molecular clocks and dated phylogenies
Mutations tend to accumulate in a clock-like fashion
"Root-to-tip" plots show temporal signal
Allows conversion between branch length and time
Dated phylogenies provide real-world context
Inference of discrete traits
"Data" is a phylogeny and tip states
States include nucleotides, amino acids, geo locations, hosts, etc...
Model infers transition matrix and ancestral states
Rare transitions, short branches and many taxa increase confidence
Nesting patterns are informative
Zika phylogeny infers an origin in northeast Brazil
Acknowledgements
Bedford Lab:
Alli Black,
John Huddleston,
Barney Potter,
James Hadfield,
Louise Moncla,
Tom Sibley,
Maya Lewinsohn,
Katie Kistler
Nextstrain: Richard Neher, James Hadfield, Emma Hodcroft, Tom Sibley, John Huddleston,
Sidney Bell, Barney Potter, Colin Megill, Charlton Callender


Our Galactic Neighborhood
This is a simulation of almost 110,000 charted stars in our galaxy, with our sun and earth at the center. Each star is accurately colored and proportionately scaled based on its absolute magnitude. Sliders allow you to zoom in and out, and see how the stars and constellations are moving over the eons (NOTE: no gravity calculations, just based on linear velocity so kind of a rough estimate).
Very special thanks to astronexus.com for their Hyg stellar database and to Pierre Barbier for his asterism definitions.
I am not a scientist, but if you are, and have ideas about how this simulation might be improved, I would love to talk to you about it, drop me a line.


| conditionList {unitizer} | R Documentation |
Condition lists are S4 classes that contain condition
objects
emitted by unitizer
tests. Condition lists will typically be
accessible via the .NEW
and .REF
unitizer
test objects.
You can access individual conditions using [[
(see examples), and for
the most part you can treat them as you would an S3 list containing
conditions.
There are show
and all.equal
methods implemented for them, the
latter of which is used to compare conditions across tests. If you wish to
implement a custom comparison function via unitizer_sect
, your
function will need to compare conditionList
objects.
.items
list of conditions
Implemented as an S4 class to avoid setOldClass
and related
compatibility issues; the conditionList
class contains
unitizerList
.
unitizer_sect
, unitizerList
,
all.equal.conditionList
## Create a test item as you would find normally at the `unitizer` prompt ## for illustrative purposes: .NEW <- mock_item() ## Access the first condition from the new test evaluation .NEW$conditions[[1L]] ## loop through all conditions for(i in seq_along(.NEW$conditions)) .NEW$conditions[[i]]


Home
Hud
Debug
Minority Report
Log In
User
None
New User Name
Session
None
Session Name
Session Description
Instance Configuration
None
Camera URI
Kinect URI
Redefine Canvas Points
×
Canvas Location
Redefine Kinect Canvas Points
×
Canvas Location
Your browser does not support the HTML5 canvas tag.
Show lines
Show stickyNotes
Add line
Add stickyNote


What would happen if there was massive shotdown we have a video to explain it best.
Warning! If the 433 world nuclear plants explode: first problay it will be some secure places in the world in the first moments, but first will be a world panic the minus problem we be the nuclear energy ...after will be so much contamition in all places, lack of resources, etc. As you can see a CHAOS!


Statistics stores a number of double values and computes descriptive statistics out of them.
The element is just an object of the DescriptiveStatistics class in the Apache Common numerics library.
To add a statistics element to your model, simply drag the icon element to the list of your model elements.
A call to the element method void addValue(double value) adds a double value to the dataset.
A call to the element method void clear() clears all data previously added.
The element provides several methods to retrieve descriptive statistics out of the data added. Here are just two of them:
statistics.clear(); // Make sure the dataset is empty statistics.addValue(1); statistics.addValue(1); statistics.addValue(1); statistics.addValue(2); _println("Mean = "+statistics.getMean()); // prints: Mean = 1.25 _println("Variance = "+statistics.getVariance()); // prints: Variance = 0.25


"Forget this world and all its troubles and if possible its multitudinous Charlatans—every thing in short but the Enchantress of Number." - Charles Babbage, 1843
Ada Lovelace
The First Computer Programmer
A portrait of Ada Lovelace with a diagram from her notes behind her. The diagram shows the variables to be used by Babbage's Difference Engine.
Timeline of Lovelace's life:
1815 - Born Augusta Ada Byron in London, England to Lady Wentworth and Lord Byron.
1816 - Her parents separate. Lord Byron leaves the country and dies eight years later, never having returned.
1832 - Her mathematical abilities and interest in the subject, including differential calculus, begin to become apparent.
1833 - Meets Charles Babbage, through Ada's private tutor Mary Somerville.
1835 - Marries William King, becoming Lady King.
1838 - Becomes Countess of Lovelace.
1842 - 1843 - Over a nine month period Lovelace translates an article on Babbage's Difference engine written by Luigi Menabrea, an Italian engineer. Her notes on the article include what is now considered to be the first computer program.
1844
Expresses an interest in creating a mathematical model to describe the workings of the human brain, although this is never completed.
Learns to experiment with electricity from engineer Charles Cross.
Reviews an article called Researches in Magnetism that is never published.
1852 - Dies of uterine cancer, age 36.
1953 - Lovelace's notes on the Analytical Engine are republished.
You can read more about Ada Lovelace on her Wikipedia entry.


Recipe 10.8. Selectively Copying a Mailbox File
Credit: Noah Spurrier, Dave Benjamin
Problem
You need to selectively copy
a large mailbox file (in mbox style), passing each
message through a filtering function that may alter or skip the
message.
Solution
The Python Standard Library package email is the
modern Python approach for this kind of task. However, standard
library modules mailbox and
rfc822 can also supply the base functionality to
implement this task:
def process_mailbox(mailboxname_in, mailboxname_out, filter_function):
mbin = mailbox.PortableUnixMailbox(file(mailboxname_in,'r'))
fout = file(mailboxname_out, 'w')
for msg in mbin:
if msg is None: break
document = filter_function(msg, msg.fp.read( ))
if document:
assert document.endswith('\n\n')
fout.write(msg.unixfrom)
fout.writelines(msg.headers)
fout.write('\n')
fout.write(document)
fout.close( )
Discussion
I often write lots of little scripts to filter my mailbox, so I wrote
this recipe's small module. I can import the module
from each script and call the module's function
process_mailbox as needed. Python's
future direction is to perform email processing with the standard
library package email, but lower-level modules,
such as mailbox and rfc822, are
still available in the Python Standard Library. They are sometimes
easier to use than the rich, powerful, and very general functionality
offered by package email.
The function you pass to process_mailbox as the
third argument, filter_function, must take two
argumentsmsg, an rfc822
message object, and document, a string that is the
message's entire body, ending with two line-end
characters (\n\n).
filter_function can return False,
meaning that this message must be skipped (i.e., not copied at all to
the output), or else it must return a string terminated with
\n\n that is written to the output as the message
body. Normally, filter_function returns either
False or the same document
argument it was called with, but in some cases you may find it useful
to write to the output file an altered version of the
message's body rather than the original message
body.
Here is an example of a filter function that removes duplicate
messages:
import sets
found_ids = sets.Set( )
def no_duplicates(msg, document):
msg_id = msg.getheader('Message-ID')
if msg_id in found_ids:
return False
found_ids.add(msg_id)
return document
In Python 2.4, you could use the built-in set
rather than sets.Set, but for a case as simple as
this, it makes no real difference in performance (and the usage is
exactly the same, anyway).
See Also
Documentation about modules mailbox and
rfc822, and package email, in
the Library Reference and Python in
a Nutshell.
|


Start
Start2
This test is expected to only play the 'start2' sound on iOS, both on Chrome @ Android (even simultaniously), either on native Android (if attempting to play the second sound while first is playing, second sound will be permanently disabled).


Love, etc.
(France, 1996; French with English subtitles)
Seen on 2 April 1997 for 5 pounds by myself at the Curzon Mayfair, London.
*Love, etc.* is one of those artsy French films that give good French art films a bad name. It is full of uninteresting characters with incomprehensible motivations and a lot of annoying touches that are supposed to make it more "fascinating." Truffaut's Jules et Jim is the film to which this one is compared, but Jules et Jim it ain't.
The hook in *Love, etc.* is the "odd couple" friendship of Benoit (Yvan Attal) and Pierre Thibault de Montalembert. The former is shy and odd, and not lucky with the ladies, while the latter is cocky and confident and usually arranged the blind dates. Personally, I thought Benoit was much cuter than Pierre, and I guess a zero of self-esteem makes him such a schlub that when he eventually meets Marie (Charlotte Gainsbourg) via a personal ad, it is Pierre's photo he sends to her.
So, Benoit and Marie fall in love and get married, but something odd develops between Pierre and Marie. The film's most interesting moment, cinematically, is when the wedding photos are being taken and the three principal characters speak directly to the camera about how they are feeling, while the rest of the image is still.
What ensues is painful: Pierre starts harassing Marie with protestations of love soon after the wedding. Eventually, Marie's resistance is broken and all three characters get twisted in the inevitable emotional wreckage.
I guess what bothered me most about this movie was that it confirms every horrible feeling you have about humankind. It's horrible to see a "best friend" betray another, simply because he decides at the last minute he is in love with the man's wife. Marring the film also is the "artistic" inclusion of music that is supposed to be a fine little touch, but gets very annoying very quickly.
The best performance belongs to Attal as the wronged husband and lonely soul, as he vents his rage on Marie and Pierre once he finds out he's been betrayed.
THEATRE NOTE: Despite reserved seating and plush seats, and an attentive and courteous staff, a gaggle of annoying women still had to be shushed by yours truly during the dramatic highpoint of the film. This seems to be a worldwide phenomenon.
Based on a novel by Julian Barnes. Directed by Marion Vernoux.
More movie reviews by Seth Bookey, with graphics, can be found at http://www.geocities.com/Athens/2679/kino.html
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


{include file="head" /} {block name="head"}{/block}
{block name="main"}{/block} {block name="footer"}{/block}


ORE
Database
Tables
(current)
Columns
Constraints
Relationships
Orphan Tables
Anomalies
Utility Tables
Orphan Tables


ToDO without crud
Walk Snowy
Review Pull Request
Start Contributing to OpenSource projects
Learn VueJS


Short description here maybe? Could look good, you never know.
Interesting facts and findings we discovered being the awesome agency we are. Lots of info or little, up to you guys
Interesting facts and findings we discovered being the awesome agency we are. Lots of info or little, up to you guys
Interesting facts and findings we discovered being the awesome agency we are. Lots of info or little, up to you guys
Interesting facts and findings we discovered being the awesome agency we are. Lots of info or little, up to you guys


We're taking part in Advent of Code!
🎄
👩💻
🎄
👨💻
🎄
Head over to
https://adventofcode.com
to see the puzzles each day, then head over to
https://hacksoc.net/discord
and join us solving programming challenges
until December 25th!


 All around you are groups of four computers. Each group consists of a desktop computer, keyboard, mouse, table and a chair. The four tables are curved so when pushed up next to each other they make a circular pod. At each pod station there is a sign that says no food or drink. Also, a sign that says no cell phone calls. As you see the sign someone’s cell phone rings, and they answer it. You decide to sit down to use a computer. Once you are in the chair you notice you need a library card number and pin to log on.
| No Problem I got a New/Replacement Card earlier | ||
| . . . . . | . . . . . | |
| I need to get back to the front desk to get a Card |


Brand improvement focuses on filling the gaps between your current brand strategy platform and your desired brand strategy platform that you completed in chapter 4. Let’s revisit sections of our Brand Strategy Platform to see a sampling of brand improvements for some of our individual branding examples.
| Strengths (Cake) | |
| Hard Skills | ←Hard Skills. Bob, the unemployed computer programmer, needed to develop more skills in the area of web software development. He can take courses, read technical books and do pro bono programming to gain these skills. |
| Soft Skills | ←Soft Skills. Eileen, who wanted to become vice president of marketing, needed to work on her collaboration and leadership skills. She can work with an executive coach, take courses, read business books and look for opportunities to learn from others. |
| Expertise | ←Expertise. Marnie, who wanted to be an elder care sales specialist, had to volunteer, network and do Internet research to gain the expertise and experience she needed to change careers from retail sales. |
| Personality (Icing) | |
| Personality Attributes | ←Personality. Eileen needed to create a more empathetic personality to be more effective in a collaborative corporate culture. She can work with her executive coach or mentor on this change. |
| Type of leader, worker, friend | |
| Brand Metaphor |
| Brand Image (Cake & Icing) | |
| Brand Associations | |
| External Image | ←External Image. Alison, the corporate lawyer, upgraded her wardrobe, got a sleeker and more professional hairstyle and projected more confidence to enhance being seen as the strategic IP lawyer that she was. |
| Relationship Image |
| Brand Promise (Cake & Icing) | |
| Rational Value | |
| Emotional Value | |
| Brand Experience | ←Brand Experience. Candidate Hillary’s brand promise included “solving problems with citizen engagement,” so she needed to increase her opportunities to LISTEN and learn from residents. |
Figure 6.5 is a sample brand improvement template. As you look at the gaps between your current brand and desired brand in the Brand Strategy Platform, you will recognize areas where you need to improve. I have populated this brand improvement template with some areas that are key to strong brands. However, you can customize the Key Areas to Improve column to the specific areas in which you need work.
To access PDF version, go to www.brandingpays.com/resources
To give you an idea of what a high-level brand improvement plan might look like, see Fig. 6.6. The Rating column should be filled with a number, with 1 indicating very low achievement and 5, very high achievement. This number should reflect how you are currently perceived based on your own assessment and feedback from others. Over time, your goal should be to raise all of your scores to a 4 or 5.
Put what may be holding you back in the Challenge column. In Priority Actions, list a few key actions you can take to change your behavior and people’s perceptions of you. In Allies and Tools, identify the BrandingPays tool and other people and resources who could help you to make the improvements you seek.


This is an awesome message!
SMS 13:37
I agree that your message is awesome!
SMS 13:37
Thanks!
SMS 13:37


Rugrats
Ren & Stimpy
Doug
Rocko's Modern Life
The Adventures of Pete & Pete
Clarissa Explains it All
Legends of the hidden temple
Double Dare


Here are my pets
They are very awesome
Fish
Cat
Dog
Bird
Guinea pig
Click
here
to check out my other pets.


| JOB DESCRIPTION | EDIT |
| POSITION TITLE | Customer Service Representative |
| LOCATION | San Francisco, CA |
| EMPLOYMENT TYPE | Full Time |
| EXPERIENCE | Mid-level |
| STATUS | Open |
| DESCRIPTION | Developer skillfully captures the spirit and design intent of all comp details. Execution is pixel-perfect and any design decisions left open to interpretation are solved intentionally, are as seamless as if the designer had provided the solution, are handled gracefully, and enhance the overall design. |
| HIRING LEAD | Tim Tizzy |
| APPROVED SALARY | $58,0000 |
The purrr-fect lorem ipsum generator for clients who love their cats and cat memes.
The purrr-fect lorem ipsum generator for clients who love their cats and cat memes.
The purrr-fect lorem ipsum generator for clients who love their cats and cat memes.


This is a demonstration of thebe-core starting up and connecting to a Jupyter server, then executing 3 cell via the notebook interface
thebe-code can connect to the following server types
You'll need to start your local jupyter server on port 8888 and like this:
jupyter notebook --NotebookApp.token=test-secret --NotebookApp.allow_origin="*"
The page immediately requests a kernel and the kernel status can be monitored via simple messaging callbacks
Current server status is none and session/kernel status is none


Mushroom
Mushroom is a Green food. Green foods are safe to eat as a regular part of a diet.
Category Quotes
Guideline related quotes related to Non-Starchy and Green throughout Geoff Bond's publications.
Eat at least 2 3/4 lbs of mixed salad and vegetables per day, consisting of "Green-Green” and “Green” foods. Of these, at least 3/4 lb should be mixed salad. Also include at least 5 cups of “Green-Green” leafy vegetables or 2 1/2 cups of other vegetables per week. ~Paleo in a Nutshell p.102
Additional Quotes
Specific references to Mushroom throughout Geoff Bond's publications.
our ancestors knew they were living in a dangerous, treacherous, and unpredictable jungle. They had the skills to survive: They knew how to circumvent a hungry leopard and which mushrooms were poisonous. This book teaches you the skills to survive in today's "supermarket jungle." ~Paleo in a Nutshell p.3
It is quite easy really to achieve six servings by eating one big salad every day with all the usual ingredients we think of as salad vegetables: Tomatoes, lettuce, radish, cucumber, mushrooms, onions, and so forth. ~Paleo in a Nutshell p.48
Conforming non-starchy, colored plant foods are foods that are low-glycemic, rich in micronutrients and fiber, and harmless with regard to anti-nutrients and antigens. Broadly, they include most salad foods, such as lettuce, onions, cucumber, radish, and mushrooms, and they also include colored vegetables, such as broccoli, green beans, bell peppers (sweet peppers), and Brussels sprouts. These are considered "Green-Green," "Green," and "Green-Amber." Under "Green-Green," we have separated out the vegetables that have the high concentrations of background micronutrients that our ancient ancestors delighted in. You can have unlimited consumption of these foods, and the ideal is up to two pounds (900 g) per day. ~Paleo in a Nutshell p.62
Old-Fashioned Haddock Breakfast. This used to be a good standby in many parts of the English-speaking world. Many people are old enough to remember, perhaps, when their grandparents used to eat like this. They would lightly poach a piece of haddock (or kipper or any other appropriate fish) in simmering water for about five minutes. They would accompany it with lashings of sauteed onion, grilled tomatoes, and mushrooms. ~Paleo in a Nutshell p.88
Eating in fast-food restaurants is a little harder. Find a salad, if you can; discard the packet of salad dressing, unless it is simple oil and vinegar. Consider carrying a bottle of your own vinaigrette. Or eat the all-day breakfast: Eggs with tomatoes and mushrooms (without bread or roll) are acceptable, but avoid the bacon, sausage, hash browns, toast, waffles, syrup, and muffins. It is not ideal to eat the processed meat in fast-food restaurants, but if you must, order the burger (no cheese) or grilled chicken sandwich and throw away the bun. ~Paleo in a Nutshell p.90
The vegetables from above ground cover a huge range of plant parts: stems, such as asparagus from the Mediterranean and kohlrabi from Europe; buds, such as Brussels sprouts from Belgium; leafstalks, such as celery from the Mediterranean and rhubarb from Asia; leaves, such as Europe's cabbage, lettuce, and spinach; immature flowers, such as cauliflower from Europe, broccoli from Turkey, and artichoke from the western Mediterranean; immature fruits, such as eggplant from southern Asia and cucumber from northern India; mature "vegetable-fruits," such as tomato from Peru, avocado from Central America, and bell pepper from the Andes; edible bean pods, such as runner beans from tropical America; and edible fungi (mushrooms) from just about everywhere. Of course, today, these plants are grown all over the world, wherever farmers can produce them economically. ~Deadly Harvest p.56
This overview of the science gives us the main signposts, but when it comes to food choices, we need to have a knowledge of the details as well. Our ancient ancestors had the skills to survive in the jungle. They knew which mushrooms were poisonous and when a tree would be fruiting. We will need to learn the same level of skill when navigating our way through the supermarket jungle today. However, we can finally declare that we have enough evidence to describe the basic specification for the diet that is right for the human species. That is, we can now write the "Owner's Manual." ~Deadly Harvest p.134
Eggs Any Style. Omega-3-rich, free-range eggs any style are fine to start the day. Make a hearty vegetable-filled omelet or grill some tomatoes and mushrooms with eggs any style. Don't forget that plant food should form the major part of the meal, and no backsliding— definitely no bread. ~Deadly Harvest p.161
Eating in fast-food restaurants is just the same, only harder. Resign yourself to ordering the burger and throwing away the bun. Find a salad, if you can, but discard the packet of salad dressing (consider carrying a bottle of your own vinaigrette). Or eat the all-day breakfast: eggs with tomatoes and mushrooms are acceptable, but avoid the sausage, steak, hash-browns, toast, waffles, syrup, and muffins. ~Deadly Harvest p.164


--- title: Train and evaluate the estimator. type: docs repo: https://github.com/rstudio/tfestimators menu: main: name: Train and evaluate the estimator. - tfestimators parent: tfestimators-reference aliases: - /reference/tfestimators/train_and_evaluate.tf_estimator.html - /tfestimators/reference/train_and_evaluate.tf_estimator.html - /guide/tfestimators/reference/train_and_evaluate.tf_estimator.html - /tools/tools/tfestimators/reference/train_and_evaluate.tf_estimator.html - /installation/tfestimators/reference/train_and_evaluate.tf_estimator.html - /tutorials/tfestimators/reference/train_and_evaluate.tf_estimator.html - /guide/tools/tfestimators/reference/train_and_evaluate.tf_estimator.html - /deploy/tfestimators/reference/train_and_evaluate.tf_estimator.html - /tools/tfestimators/reference/train_and_evaluate.tf_estimator.html - /tutorials/tools/tfestimators/reference/train_and_evaluate.tf_estimator.html ---
(Available since TensorFlow v1.4)
# S3 method for tf_estimator
train_and_evaluate(object, train_spec, eval_spec,
...)
| object | An estimator object to train and evaluate. |
| train_spec | A |
| eval_spec | A |
| ... | Not used. |
This utility function trains, evaluates, and (optionally) exports the model by
using the given estimator
. All training related specification is held in
train_spec
, including training input_fn
and training max steps, etc. All
evaluation and export related specification is held in eval_spec
, including
evaluation input_fn
, steps, etc.
This utility function provides consistent behavior for both local (non-distributed) and distributed configurations. Currently, the only supported distributed training configuration is between-graph replication.
Overfitting: In order to avoid overfitting, it is recommended to set up the
training input_fn
to shuffle the training data properly. It is also
recommended to train the model a little longer, say multiple epochs, before
performing evaluation, as the input pipeline starts from scratch for each
training. It is particularly important for local training and evaluation.
Stop condition: In order to support both distributed and non-distributed
configuration reliably, the only supported stop condition for model
training is train_spec.max_steps
. If train_spec.max_steps
is NULL
, the
model is trained forever. Use with care if model stop condition is
different. For example, assume that the model is expected to be trained with
one epoch of training data, and the training input_fn
is configured to throw
OutOfRangeError
after going through one epoch, which stops the
Estimator.train
. For a three-training-worker distributed configuration, each
training worker is likely to go through the whole epoch independently. So, the
model will be trained with three epochs of training data instead of one epoch.
ValueError: if environment variable TF_CONFIG
is incorrectly set.
Other training methods: eval_spec
,
train_spec


{% block style_base %}
{% endblock %}
PATRICK BUZZO
Skills
Projects
Resume
Certifications
Get In Touch
{% comment %}
PATRICK BUZZO
Skills
Projects
Resume
Certifications
Get In Touch
{% endcomment %} {% block content %} {% endblock %}


Version Info
Firmware version number: %version%
About
The POE stack light is a project by Tyler Ward
This is a open source project source code for the components can be found at the links below
Firmware version number: %version%
The POE stack light is a project by Tyler Ward
This is a open source project source code for the components can be found at the links below


2023 Presidency: Most Leaders Of Southern Nigeria Are Cowards – Fani-Kayode
by Enioluwa AdeniyiThe minister of aviation under the Goodluck Jonathan Administration, Femi Fani-Kayode, has described some leaders from the Southern part of Nigeria as cowards.
The former minister stated this while reacting to the comment by the acting Chairman of Arewa Consultative Forum, ACF, Alhaji Musa Liman Kwande, that Northerners will vote for only a presidential candidate of northern origin in 2023 presidential election irrespective of the political party.
Kwande while speaking over the weekend charged Northerners to work towards developing the region by voting for individuals who are pro-development and not those who are self-centred.
Fani-Kayode in his view stated that the alleged cowardice of Southern leaders gave room for Kwande to make such a statement.
The former minister who took to his Twitter account wrote, “In 2023 people from the northern part of the country will vote for a presidential candidate from that region irrespective of the party – Musa Liman, Acting Chairman of ACF.”
“If not for the cowardice of most southern leaders you would not have the nerve to speak like this”


Setting up Oracle 11g in Windows
A short simple guide to set up oracle database 11g on your windows system.
1. Downloading Oracle 11g express
Go to this page to get download links
Choose x64 if you have 64bit system or x32 for 32bit system. If you are not sure just select x32 one.
You will be required to signup and login to download this
and on completing the signup and login, your download will start.
2. Installing Oracle 11g
An obvious step is to extract the downloaded zip
What’s next start with double-clicking setup.exe :D
You will be asked for a password. You can put any password you want here but for now I’m putting “root” as password
Now complete setup process and that’s all in installation.
3. Using Oracle 11g
Go to your start menu and search for “SQL” you will see something “Run SQL Command Line”. Open it.
Now how to connect ? Simple!
You can directly use “Sysdba” user or if you want you can use it to create more users.
Here’s how you can login using sysdba user
Now after this you can directly use SQL commands or if you prefer, create new user to use.
This post is inspired from the questions of my batchmates so major credits goes to them


MY WORK
Although not many, I've had a wonderful time working on these projects from design to finish!
STREET FOOD WEBSITE
PROJECT BRIEF
This website, authored by Venesa Okuna, is meant to serve as a template or source of inspiration for street food or food related websites in general. Programming Languages used are HTML & CSS
view site
CONSTRUCTION WEBSITE
PROJECT BRIEF
This website, authored by Venesa Okuna, is meant to serve as a template or source of inspiration for construction or construction related websites in general. Programming Languages used are HTML & CSS
view site


Standard ECMA-262
ECMAScript® Language Specification
Edition 5.1 (June 2011)
This Standard defines the ECMAScript scripting language.
The following files can be freely downloaded:
| File name |
Size (Bytes) |
Content |
| ECMA-262.pdf |
3 270 645 |
Acrobat (r) PDF file |
| ECMA-262 html |
|
Browsable HTML |
This edition 5.1 of the ECMAScript Standard is fully aligned with third edition of the international standard ISO/IEC 16262:2011.
The previous replaced "historical" editions of this Ecma Standard are available here.
Back


|
M480 BSP V3.05.005
The Board Support Package for M480 Series
|
Macros | |
| #define | SYS_CLEAR_BOD_INT_FLAG() |
| Clear Brown-out detector interrupt flag. More... | |
| #define | SYS_CLEAR_BOD_LPM() |
| Set Brown-out detector function to normal mode. More... | |
| #define | SYS_DISABLE_BOD() |
| Disable Brown-out detector function. More... | |
| #define | SYS_ENABLE_BOD() |
| Enable Brown-out detector function. More... | |
| #define | SYS_GET_BOD_INT_FLAG() |
| Get Brown-out detector interrupt flag. More... | |
| #define | SYS_GET_BOD_OUTPUT() |
| Get Brown-out detector status. More... | |
| #define | SYS_DISABLE_BOD_RST() |
| Enable Brown-out detector interrupt function. More... | |
| #define | SYS_ENABLE_BOD_RST() |
| Enable Brown-out detector reset function. More... | |
| #define | SYS_SET_BOD_LPM() |
| Set Brown-out detector function low power mode. More... | |
| #define | SYS_SET_BOD_LEVEL(u32Level) |
| Set Brown-out detector voltage level. More... | |
| #define | SYS_IS_BOD_RST() |
| Get reset source is from Brown-out detector reset. More... | |
| #define | SYS_IS_CPU_RST() |
| Get reset source is from CPU reset. More... | |
| #define | SYS_IS_LVR_RST() |
| Get reset source is from LVR Reset. More... | |
| #define | SYS_IS_POR_RST() |
| Get reset source is from Power-on Reset. More... | |
| #define | SYS_IS_RSTPIN_RST() |
| Get reset source is from reset pin reset. More... | |
| #define | SYS_IS_SYSTEM_RST() |
| Get reset source is from system reset. More... | |
| #define | SYS_IS_WDT_RST() |
| Get reset source is from window watch dog reset. More... | |
| #define | SYS_DISABLE_LVR() |
| Disable Low-Voltage-Reset function. More... | |
| #define | SYS_ENABLE_LVR() |
| Enable Low-Voltage-Reset function. More... | |
| #define | SYS_DISABLE_POR() |
| Disable Power-on Reset function. More... | |
| #define | SYS_ENABLE_POR() |
| Enable Power-on Reset function. More... | |
| #define | SYS_CLEAR_RST_SOURCE(u32RstSrc) |
| Clear reset source flag. More... | |
Functions | |
| __STATIC_INLINE void | SYS_UnlockReg (void) |
| Disable register write-protection function. More... | |
| __STATIC_INLINE void | SYS_LockReg (void) |
| Enable register write-protection function. More... | |
| void | SYS_ClearResetSrc (uint32_t u32Src) |
| Clear reset source. More... | |
| uint32_t | SYS_GetBODStatus (void) |
| Get Brown-out detector output status. More... | |
| uint32_t | SYS_GetResetSrc (void) |
| Get reset status register value. More... | |
| uint32_t | SYS_IsRegLocked (void) |
| Check if register is locked nor not. More... | |
| uint32_t | SYS_ReadPDID (void) |
| Get product ID. More... | |
| void | SYS_ResetChip (void) |
| Reset chip with chip reset. More... | |
| void | SYS_ResetCPU (void) |
| Reset chip with CPU reset. More... | |
| void | SYS_ResetModule (uint32_t u32ModuleIndex) |
| Reset selected module. More... | |
| void | SYS_EnableBOD (int32_t i32Mode, uint32_t u32BODLevel) |
| Enable and configure Brown-out detector function. More... | |
| void | SYS_DisableBOD (void) |
| Disable Brown-out detector function. More... | |
| void | SYS_SetPowerLevel (uint32_t u32PowerLevel) |
| Set Power Level. More... | |
| void | SYS_SetVRef (uint32_t u32VRefCTL) |
| Set Reference Voltage. More... | |
| #define SYS_CLEAR_BOD_INT_FLAG | ( | ) |
| #define SYS_CLEAR_BOD_LPM | ( | ) |
| #define SYS_CLEAR_RST_SOURCE | ( | u32RstSrc | ) |
Clear reset source flag.
| [in] | u32RstSrc | is reset source. Including : |
This macro clear reset source flag.
| #define SYS_DISABLE_BOD | ( | ) |
| #define SYS_DISABLE_BOD_RST | ( | ) |
| #define SYS_DISABLE_LVR | ( | ) |
| #define SYS_DISABLE_POR | ( | ) |
| #define SYS_ENABLE_BOD | ( | ) |
| #define SYS_ENABLE_BOD_RST | ( | ) |
| #define SYS_ENABLE_LVR | ( | ) |
| #define SYS_ENABLE_POR | ( | ) |
| #define SYS_GET_BOD_INT_FLAG | ( | ) |
| #define SYS_GET_BOD_OUTPUT | ( | ) |
Get Brown-out detector status.
| None |
| 0 | System voltage is higher than BOD threshold voltage setting or BOD function is disabled. |
| >=1 | System voltage is lower than BOD threshold voltage setting. |
This macro get Brown-out detector output status. If the BOD function is disabled, this function always return 0.
| #define SYS_IS_BOD_RST | ( | ) |
Get reset source is from Brown-out detector reset.
| None |
| 0 | Previous reset source is not from Brown-out detector reset |
| >=1 | Previous reset source is from Brown-out detector reset |
This macro get previous reset source is from Brown-out detect reset or not.
| #define SYS_IS_CPU_RST | ( | ) |
| #define SYS_IS_LVR_RST | ( | ) |
| #define SYS_IS_POR_RST | ( | ) |
| #define SYS_IS_RSTPIN_RST | ( | ) |
| #define SYS_IS_SYSTEM_RST | ( | ) |
| #define SYS_IS_WDT_RST | ( | ) |
Get reset source is from window watch dog reset.
| None |
| 0 | Previous reset source is not from window watch dog reset |
| >=1 | Previous reset source is from window watch dog reset |
This macro get previous reset source is from window watch dog reset.
| #define SYS_SET_BOD_LEVEL | ( | u32Level | ) |
Set Brown-out detector voltage level.
| [in] | u32Level | is Brown-out voltage level. Including : |
This macro set Brown-out detector voltage level. The write-protection function should be disabled before using this macro.
| #define SYS_SET_BOD_LPM | ( | ) |
| void SYS_ClearResetSrc | ( | uint32_t | u32Src | ) |
Clear reset source.
| [in] | u32Src | is system reset source. Including : |
This function clear the selected system reset source.
| void SYS_DisableBOD | ( | void | ) |
| void SYS_EnableBOD | ( | int32_t | i32Mode, |
| uint32_t | u32BODLevel | ||
| ) |
Enable and configure Brown-out detector function.
| [in] | i32Mode | is reset or interrupt mode. Including : |
| [in] | u32BODLevel | is Brown-out voltage level. Including : |
This function configure Brown-out detector reset or interrupt mode, enable Brown-out function and set Brown-out voltage level. The register write-protection function should be disabled before using this function.
| uint32_t SYS_GetBODStatus | ( | void | ) |
| uint32_t SYS_GetResetSrc | ( | void | ) |
| uint32_t SYS_IsRegLocked | ( | void | ) |
| __STATIC_INLINE void SYS_LockReg | ( | void | ) |
| uint32_t SYS_ReadPDID | ( | void | ) |
| void SYS_ResetChip | ( | void | ) |
| void SYS_ResetCPU | ( | void | ) |
| void SYS_ResetModule | ( | uint32_t | u32ModuleIndex | ) |
Reset selected module.
This function reset selected module.
| void SYS_SetPowerLevel | ( | uint32_t | u32PowerLevel | ) |
Set Power Level.
| [in] | u32PowerLevel | is power level setting. Including : |
This function select power level. The register write-protection function should be disabled before using this function.
| void SYS_SetVRef | ( | uint32_t | u32VRefCTL | ) |
Set Reference Voltage.
| [in] | u32VRefCTL | is reference voltage setting. Including : |
This function select reference voltage. The register write-protection function should be disabled before using this function.


Modular
Unlike the existing encryption models which require a key to read the message,
biSponge requires more than just a key as it requires many certain conditions to be checked then only it decrypts.
Unconventional
It is a symmetric key based system but a wrong key will also generate a password, though obviously wrong key will always give wrong password.
This unconventional approach defeats any hit and trial method like brute force to whom which other encryption systems are prone to.


/*globals Ember*/
/*jshint eqnull:true*/
/**
@module ember-data
*/
import {
InvalidError,
Adapter
} from "ember-data/system/adapter";
import { singularize } from "ember-inflector/system/string";
import {
Map
} from "ember-data/system/map";
import {
promiseArray,
promiseObject
} from "ember-data/system/promise_proxies";
var get = Ember.get;
var set = Ember.set;
var once = Ember.run.once;
var isNone = Ember.isNone;
var forEach = Ember.EnumerableUtils.forEach;
var indexOf = Ember.EnumerableUtils.indexOf;
var map = Ember.EnumerableUtils.map;
var Promise = Ember.RSVP.Promise;
var copy = Ember.copy;
var Store, RecordArrayManager, Model;
var camelize = Ember.String.camelize;
// Implementors Note:
//
// The variables in this file are consistently named according to the following
// scheme:
//
// * +id+ means an identifier managed by an external source, provided inside
// the data provided by that source. These are always coerced to be strings
// before being used internally.
// * +clientId+ means a transient numerical identifier generated at runtime by
// the data store. It is important primarily because newly created objects may
// not yet have an externally generated id.
// * +reference+ means a record reference object, which holds metadata about a
// record, even if it has not yet been fully materialized.
// * +type+ means a subclass of DS.Model.
// Used by the store to normalize IDs entering the store. Despite the fact
// that developers may provide IDs as numbers (e.g., `store.find(Person, 1)`),
// it is important that internally we use strings, since IDs may be serialized
// and lose type information. For example, Ember's router may put a record's
// ID into the URL, and if we later try to deserialize that URL and find the
// corresponding record, we will not know if it is a string or a number.
function coerceId(id) {
return id == null ? null : id+'';
}
/**
The store contains all of the data for records loaded from the server.
It is also responsible for creating instances of `DS.Model` that wrap
the individual data for a record, so that they can be bound to in your
Handlebars templates.
Define your application's store like this:
```javascript
MyApp.Store = DS.Store.extend();
```
Most Ember.js applications will only have a single `DS.Store` that is
automatically created by their `Ember.Application`.
You can retrieve models from the store in several ways. To retrieve a record
for a specific id, use `DS.Store`'s `find()` method:
```javascript
store.find('person', 123).then(function (person) {
});
```
By default, the store will talk to your backend using a standard
REST mechanism. You can customize how the store talks to your
backend by specifying a custom adapter:
```javascript
MyApp.ApplicationAdapter = MyApp.CustomAdapter
```
You can learn more about writing a custom adapter by reading the `DS.Adapter`
documentation.
### Store createRecord() vs. push() vs. pushPayload()
The store provides multiple ways to create new record objects. They have
some subtle differences in their use which are detailed below:
[createRecord](#method_createRecord) is used for creating new
records on the client side. This will return a new record in the
`created.uncommitted` state. In order to persist this record to the
backend you will need to call `record.save()`.
[push](#method_push) is used to notify Ember Data's store of new or
updated records that exist in the backend. This will return a record
in the `loaded.saved` state. The primary use-case for `store#push` is
to notify Ember Data about record updates (full or partial) that happen
outside of the normal adapter methods (for example
[SSE](http://dev.w3.org/html5/eventsource/) or [Web
Sockets](http://www.w3.org/TR/2009/WD-websockets-20091222/)).
[pushPayload](#method_pushPayload) is a convenience wrapper for
`store#push` that will deserialize payloads if the
Serializer implements a `pushPayload` method.
Note: When creating a new record using any of the above methods
Ember Data will update `DS.RecordArray`s such as those returned by
`store#all()`, `store#findAll()` or `store#filter()`. This means any
data bindings or computed properties that depend on the RecordArray
will automatically be synced to include the new or updated record
values.
@class Store
@namespace DS
@extends Ember.Object
*/
Store = Ember.Object.extend({
/**
@method init
@private
*/
init: function() {
// internal bookkeeping; not observable
if (!RecordArrayManager) { RecordArrayManager = requireModule("ember-data/system/record_array_manager")["default"]; }
this.typeMaps = {};
this.recordArrayManager = RecordArrayManager.create({
store: this
});
this._pendingSave = [];
//Used to keep track of all the find requests that need to be coalesced
this._pendingFetch = Map.create();
},
/**
The adapter to use to communicate to a backend server or other persistence layer.
This can be specified as an instance, class, or string.
If you want to specify `App.CustomAdapter` as a string, do:
```js
adapter: 'custom'
```
@property adapter
@default DS.RESTAdapter
@type {DS.Adapter|String}
*/
adapter: '-rest',
/**
Returns a JSON representation of the record using a custom
type-specific serializer, if one exists.
The available options are:
* `includeId`: `true` if the record's ID should be included in
the JSON representation
@method serialize
@private
@param {DS.Model} record the record to serialize
@param {Object} options an options hash
*/
serialize: function(record, options) {
return this.serializerFor(record.constructor.typeKey).serialize(record, options);
},
/**
This property returns the adapter, after resolving a possible
string key.
If the supplied `adapter` was a class, or a String property
path resolved to a class, this property will instantiate the
class.
This property is cacheable, so the same instance of a specified
adapter class should be used for the lifetime of the store.
@property defaultAdapter
@private
@return DS.Adapter
*/
defaultAdapter: Ember.computed('adapter', function() {
var adapter = get(this, 'adapter');
Ember.assert('You tried to set `adapter` property to an instance of `DS.Adapter`, where it should be a name or a factory', !(adapter instanceof Adapter));
if (typeof adapter === 'string') {
adapter = this.container.lookup('adapter:' + adapter) || this.container.lookup('adapter:application') || this.container.lookup('adapter:-rest');
}
if (DS.Adapter.detect(adapter)) {
adapter = adapter.create({
container: this.container
});
}
return adapter;
}),
// .....................
// . CREATE NEW RECORD .
// .....................
/**
Create a new record in the current store. The properties passed
to this method are set on the newly created record.
To create a new instance of `App.Post`:
```js
store.createRecord('post', {
title: "Rails is omakase"
});
```
@method createRecord
@param {String} type
@param {Object} properties a hash of properties to set on the
newly created record.
@return {DS.Model} record
*/
createRecord: function(typeName, inputProperties) {
var type = this.modelFor(typeName);
var properties = copy(inputProperties) || {};
// If the passed properties do not include a primary key,
// give the adapter an opportunity to generate one. Typically,
// client-side ID generators will use something like uuid.js
// to avoid conflicts.
if (isNone(properties.id)) {
properties.id = this._generateId(type);
}
// Coerce ID to a string
properties.id = coerceId(properties.id);
var record = this.buildRecord(type, properties.id);
// Move the record out of its initial `empty` state into
// the `loaded` state.
record.loadedData();
// Set the properties specified on the record.
record.setProperties(properties);
return record;
},
/**
If possible, this method asks the adapter to generate an ID for
a newly created record.
@method _generateId
@private
@param {String} type
@return {String} if the adapter can generate one, an ID
*/
_generateId: function(type) {
var adapter = this.adapterFor(type);
if (adapter && adapter.generateIdForRecord) {
return adapter.generateIdForRecord(this);
}
return null;
},
// .................
// . DELETE RECORD .
// .................
/**
For symmetry, a record can be deleted via the store.
Example
```javascript
var post = store.createRecord('post', {
title: "Rails is omakase"
});
store.deleteRecord(post);
```
@method deleteRecord
@param {DS.Model} record
*/
deleteRecord: function(record) {
record.deleteRecord();
},
/**
For symmetry, a record can be unloaded via the store. Only
non-dirty records can be unloaded.
Example
```javascript
store.find('post', 1).then(function(post) {
store.unloadRecord(post);
});
```
@method unloadRecord
@param {DS.Model} record
*/
unloadRecord: function(record) {
record.unloadRecord();
},
// ................
// . FIND RECORDS .
// ................
/**
This is the main entry point into finding records. The first parameter to
this method is the model's name as a string.
---
To find a record by ID, pass the `id` as the second parameter:
```javascript
store.find('person', 1);
```
The `find` method will always return a **promise** that will be resolved
with the record. If the record was already in the store, the promise will
be resolved immediately. Otherwise, the store will ask the adapter's `find`
method to find the necessary data.
The `find` method will always resolve its promise with the same object for
a given type and `id`.
---
You can optionally `preload` specific attributes and relationships that you know of
by passing them as the third argument to find.
For example, if your Ember route looks like `/posts/1/comments/2` and your API route
for the comment also looks like `/posts/1/comments/2` if you want to fetch the comment
without fetching the post you can pass in the post to the `find` call:
```javascript
store.find('comment', 2, {post: 1});
```
If you have access to the post model you can also pass the model itself:
```javascript
store.find('post', 1).then(function (myPostModel) {
store.find('comment', 2, {post: myPostModel});
});
```
This way, your adapter's `find` or `buildURL` method will be able to look up the
relationship on the record and construct the nested URL without having to first
fetch the post.
---
To find all records for a type, call `find` with no additional parameters:
```javascript
store.find('person');
```
This will ask the adapter's `findAll` method to find the records for the
given type, and return a promise that will be resolved once the server
returns the values.
---
To find a record by a query, call `find` with a hash as the second
parameter:
```javascript
store.find('person', { page: 1 });
```
This will ask the adapter's `findQuery` method to find the records for
the query, and return a promise that will be resolved once the server
responds.
@method find
@param {String or subclass of DS.Model} type
@param {Object|String|Integer|null} id
@param {Object} preload - optional set of attributes and relationships passed in either as IDs or as actual models
@return {Promise} promise
*/
find: function(type, id, preload) {
Ember.assert("You need to pass a type to the store's find method", arguments.length >= 1);
Ember.assert("You may not pass `" + id + "` as id to the store's find method", arguments.length === 1 || !Ember.isNone(id));
if (arguments.length === 1) {
return this.findAll(type);
}
// We are passed a query instead of an id.
if (Ember.typeOf(id) === 'object') {
return this.findQuery(type, id);
}
return this.findById(type, coerceId(id), preload);
},
/**
This method returns a record for a given type and id combination.
@method findById
@private
@param {String or subclass of DS.Model} type
@param {String|Integer} id
@param {Object} preload - optional set of attributes and relationships passed in either as IDs or as actual models
@return {Promise} promise
*/
findById: function(typeName, id, preload) {
var type = this.modelFor(typeName);
var record = this.recordForId(type, id);
return this._findByRecord(record, preload);
},
_findByRecord: function(record, preload) {
var fetchedRecord;
if (preload) {
record._preloadData(preload);
}
if (get(record, 'isEmpty')) {
fetchedRecord = this.scheduleFetch(record);
//TODO double check about reloading
} else if (get(record, 'isLoading')){
fetchedRecord = record._loadingPromise;
}
return promiseObject(fetchedRecord || record, "DS: Store#findByRecord " + record.typeKey + " with id: " + get(record, 'id'));
},
/**
This method makes a series of requests to the adapter's `find` method
and returns a promise that resolves once they are all loaded.
@private
@method findByIds
@param {String} type
@param {Array} ids
@return {Promise} promise
*/
findByIds: function(type, ids) {
var store = this;
return promiseArray(Ember.RSVP.all(map(ids, function(id) {
return store.findById(type, id);
})).then(Ember.A, null, "DS: Store#findByIds of " + type + " complete"));
},
/**
This method is called by `findById` if it discovers that a particular
type/id pair hasn't been loaded yet to kick off a request to the
adapter.
@method fetchRecord
@private
@param {DS.Model} record
@return {Promise} promise
*/
fetchRecord: function(record) {
var type = record.constructor;
var id = get(record, 'id');
var adapter = this.adapterFor(type);
Ember.assert("You tried to find a record but you have no adapter (for " + type + ")", adapter);
Ember.assert("You tried to find a record but your adapter (for " + type + ") does not implement 'find'", adapter.find);
var promise = _find(adapter, this, type, id, record);
return promise;
},
scheduleFetchMany: function(records) {
return Ember.RSVP.all(map(records, this.scheduleFetch, this));
},
scheduleFetch: function(record) {
var type = record.constructor;
if (isNone(record)) { return null; }
if (record._loadingPromise) { return record._loadingPromise; }
var resolver = Ember.RSVP.defer('Fetching ' + type + 'with id: ' + record.get('id'));
var recordResolverPair = {
record: record,
resolver: resolver
};
var promise = resolver.promise;
record.loadingData(promise);
if (!this._pendingFetch.get(type)){
this._pendingFetch.set(type, [recordResolverPair]);
} else {
this._pendingFetch.get(type).push(recordResolverPair);
}
Ember.run.scheduleOnce('afterRender', this, this.flushAllPendingFetches);
return promise;
},
flushAllPendingFetches: function(){
if (this.isDestroyed || this.isDestroying) {
return;
}
this._pendingFetch.forEach(this._flushPendingFetchForType, this);
this._pendingFetch = Map.create();
},
_flushPendingFetchForType: function (recordResolverPairs, type) {
var store = this;
var adapter = store.adapterFor(type);
var shouldCoalesce = !!adapter.findMany && adapter.coalesceFindRequests;
var records = Ember.A(recordResolverPairs).mapBy('record');
function _fetchRecord(recordResolverPair) {
recordResolverPair.resolver.resolve(store.fetchRecord(recordResolverPair.record));
}
function resolveFoundRecords(records) {
forEach(records, function(record){
var pair = Ember.A(recordResolverPairs).findBy('record', record);
if (pair){
var resolver = pair.resolver;
resolver.resolve(record);
}
});
}
function makeMissingRecordsRejector(requestedRecords) {
return function rejectMissingRecords(resolvedRecords) {
var missingRecords = requestedRecords.without(resolvedRecords);
rejectRecords(missingRecords);
};
}
function makeRecordsRejector(records) {
return function (error) {
rejectRecords(records, error);
};
}
function rejectRecords(records, error) {
forEach(records, function(record){
var pair = Ember.A(recordResolverPairs).findBy('record', record);
if (pair){
var resolver = pair.resolver;
resolver.reject(error);
}
});
}
if (recordResolverPairs.length === 1) {
_fetchRecord(recordResolverPairs[0]);
} else if (shouldCoalesce) {
var groups = adapter.groupRecordsForFindMany(this, records);
forEach(groups, function (groupOfRecords) {
var requestedRecords = Ember.A(groupOfRecords);
var ids = requestedRecords.mapBy('id');
if (ids.length > 1) {
_findMany(adapter, store, type, ids, requestedRecords).
then(resolveFoundRecords).
then(makeMissingRecordsRejector(requestedRecords)).
then(null, makeRecordsRejector(requestedRecords));
} else if (ids.length === 1) {
var pair = Ember.A(recordResolverPairs).findBy('record', groupOfRecords[0]);
_fetchRecord(pair);
} else {
Ember.assert("You cannot return an empty array from adapter's method groupRecordsForFindMany", false);
}
});
} else {
forEach(recordResolverPairs, _fetchRecord);
}
},
/**
Get a record by a given type and ID without triggering a fetch.
This method will synchronously return the record if it is available in the store,
otherwise it will return `null`. A record is available if it has been fetched earlier, or
pushed manually into the store.
_Note: This is an synchronous method and does not return a promise._
```js
var post = store.getById('post', 1);
post.get('id'); // 1
```
@method getById
@param {String or subclass of DS.Model} type
@param {String|Integer} id
@return {DS.Model|null} record
*/
getById: function(type, id) {
if (this.hasRecordForId(type, id)) {
return this.recordForId(type, id);
} else {
return null;
}
},
/**
This method is called by the record's `reload` method.
This method calls the adapter's `find` method, which returns a promise. When
**that** promise resolves, `reloadRecord` will resolve the promise returned
by the record's `reload`.
@method reloadRecord
@private
@param {DS.Model} record
@return {Promise} promise
*/
reloadRecord: function(record) {
var type = record.constructor;
var adapter = this.adapterFor(type);
var id = get(record, 'id');
Ember.assert("You cannot reload a record without an ID", id);
Ember.assert("You tried to reload a record but you have no adapter (for " + type + ")", adapter);
Ember.assert("You tried to reload a record but your adapter does not implement `find`", adapter.find);
return this.scheduleFetch(record);
},
/**
Returns true if a record for a given type and ID is already loaded.
@method hasRecordForId
@param {String or subclass of DS.Model} type
@param {String|Integer} id
@return {Boolean}
*/
hasRecordForId: function(typeName, inputId) {
var type = this.modelFor(typeName);
var id = coerceId(inputId);
return !!this.typeMapFor(type).idToRecord[id];
},
/**
Returns id record for a given type and ID. If one isn't already loaded,
it builds a new record and leaves it in the `empty` state.
@method recordForId
@private
@param {String or subclass of DS.Model} type
@param {String|Integer} id
@return {DS.Model} record
*/
recordForId: function(typeName, inputId) {
var type = this.modelFor(typeName);
var id = coerceId(inputId);
var idToRecord = this.typeMapFor(type).idToRecord;
var record = idToRecord[id];
if (!record || !idToRecord[id]) {
record = this.buildRecord(type, id);
}
return record;
},
/**
@method findMany
@private
@param {DS.Model} owner
@param {Array} records
@param {String or subclass of DS.Model} type
@param {Resolver} resolver
@return {DS.ManyArray} records
*/
findMany: function(records) {
var store = this;
return Promise.all( map(records, function(record) {
return store._findByRecord(record);
}));
},
/**
If a relationship was originally populated by the adapter as a link
(as opposed to a list of IDs), this method is called when the
relationship is fetched.
The link (which is usually a URL) is passed through unchanged, so the
adapter can make whatever request it wants.
The usual use-case is for the server to register a URL as a link, and
then use that URL in the future to make a request for the relationship.
@method findHasMany
@private
@param {DS.Model} owner
@param {any} link
@param {String or subclass of DS.Model} type
@return {Promise} promise
*/
findHasMany: function(owner, link, type) {
var adapter = this.adapterFor(owner.constructor);
Ember.assert("You tried to load a hasMany relationship but you have no adapter (for " + owner.constructor + ")", adapter);
Ember.assert("You tried to load a hasMany relationship from a specified `link` in the original payload but your adapter does not implement `findHasMany`", adapter.findHasMany);
return _findHasMany(adapter, this, owner, link, type);
},
/**
@method findBelongsTo
@private
@param {DS.Model} owner
@param {any} link
@param {Relationship} relationship
@return {Promise} promise
*/
findBelongsTo: function(owner, link, relationship) {
var adapter = this.adapterFor(owner.constructor);
Ember.assert("You tried to load a belongsTo relationship but you have no adapter (for " + owner.constructor + ")", adapter);
Ember.assert("You tried to load a belongsTo relationship from a specified `link` in the original payload but your adapter does not implement `findBelongsTo`", adapter.findBelongsTo);
return _findBelongsTo(adapter, this, owner, link, relationship);
},
/**
This method delegates a query to the adapter. This is the one place where
adapter-level semantics are exposed to the application.
Exposing queries this way seems preferable to creating an abstract query
language for all server-side queries, and then require all adapters to
implement them.
This method returns a promise, which is resolved with a `RecordArray`
once the server returns.
@method findQuery
@private
@param {String or subclass of DS.Model} type
@param {any} query an opaque query to be used by the adapter
@return {Promise} promise
*/
findQuery: function(typeName, query) {
var type = this.modelFor(typeName);
var array = this.recordArrayManager
.createAdapterPopulatedRecordArray(type, query);
var adapter = this.adapterFor(type);
Ember.assert("You tried to load a query but you have no adapter (for " + type + ")", adapter);
Ember.assert("You tried to load a query but your adapter does not implement `findQuery`", adapter.findQuery);
return promiseArray(_findQuery(adapter, this, type, query, array));
},
/**
This method returns an array of all records adapter can find.
It triggers the adapter's `findAll` method to give it an opportunity to populate
the array with records of that type.
@method findAll
@private
@param {String or subclass of DS.Model} type
@return {DS.AdapterPopulatedRecordArray}
*/
findAll: function(typeName) {
var type = this.modelFor(typeName);
return this.fetchAll(type, this.all(type));
},
/**
@method fetchAll
@private
@param {DS.Model} type
@param {DS.RecordArray} array
@return {Promise} promise
*/
fetchAll: function(type, array) {
var adapter = this.adapterFor(type);
var sinceToken = this.typeMapFor(type).metadata.since;
set(array, 'isUpdating', true);
Ember.assert("You tried to load all records but you have no adapter (for " + type + ")", adapter);
Ember.assert("You tried to load all records but your adapter does not implement `findAll`", adapter.findAll);
return promiseArray(_findAll(adapter, this, type, sinceToken));
},
/**
@method didUpdateAll
@param {DS.Model} type
*/
didUpdateAll: function(type) {
var findAllCache = this.typeMapFor(type).findAllCache;
set(findAllCache, 'isUpdating', false);
},
/**
This method returns a filtered array that contains all of the known records
for a given type.
Note that because it's just a filter, it will have any locally
created records of the type.
Also note that multiple calls to `all` for a given type will always
return the same RecordArray.
Example
```javascript
var localPosts = store.all('post');
```
@method all
@param {String or subclass of DS.Model} type
@return {DS.RecordArray}
*/
all: function(typeName) {
var type = this.modelFor(typeName);
var typeMap = this.typeMapFor(type);
var findAllCache = typeMap.findAllCache;
if (findAllCache) { return findAllCache; }
var array = this.recordArrayManager.createRecordArray(type);
typeMap.findAllCache = array;
return array;
},
/**
This method unloads all of the known records for a given type.
```javascript
store.unloadAll('post');
```
@method unloadAll
@param {String or subclass of DS.Model} type
*/
unloadAll: function(type) {
var modelType = this.modelFor(type);
var typeMap = this.typeMapFor(modelType);
var records = typeMap.records.slice();
var record;
for (var i = 0; i < records.length; i++) {
record = records[i];
record.unloadRecord();
record.destroy(); // maybe within unloadRecord
}
typeMap.findAllCache = null;
},
/**
Takes a type and filter function, and returns a live RecordArray that
remains up to date as new records are loaded into the store or created
locally.
The callback function takes a materialized record, and returns true
if the record should be included in the filter and false if it should
not.
The filter function is called once on all records for the type when
it is created, and then once on each newly loaded or created record.
If any of a record's properties change, or if it changes state, the
filter function will be invoked again to determine whether it should
still be in the array.
Optionally you can pass a query which will be triggered at first. The
results returned by the server could then appear in the filter if they
match the filter function.
Example
```javascript
store.filter('post', {unread: true}, function(post) {
return post.get('unread');
}).then(function(unreadPosts) {
unreadPosts.get('length'); // 5
var unreadPost = unreadPosts.objectAt(0);
unreadPost.set('unread', false);
unreadPosts.get('length'); // 4
});
```
@method filter
@param {String or subclass of DS.Model} type
@param {Object} query optional query
@param {Function} filter
@return {DS.PromiseArray}
*/
filter: function(type, query, filter) {
var promise;
var length = arguments.length;
var array;
var hasQuery = length === 3;
// allow an optional server query
if (hasQuery) {
promise = this.findQuery(type, query);
} else if (arguments.length === 2) {
filter = query;
}
type = this.modelFor(type);
if (hasQuery) {
array = this.recordArrayManager.createFilteredRecordArray(type, filter, query);
} else {
array = this.recordArrayManager.createFilteredRecordArray(type, filter);
}
promise = promise || Promise.cast(array);
return promiseArray(promise.then(function() {
return array;
}, null, "DS: Store#filter of " + type));
},
/**
This method returns if a certain record is already loaded
in the store. Use this function to know beforehand if a find()
will result in a request or that it will be a cache hit.
Example
```javascript
store.recordIsLoaded('post', 1); // false
store.find('post', 1).then(function() {
store.recordIsLoaded('post', 1); // true
});
```
@method recordIsLoaded
@param {String or subclass of DS.Model} type
@param {string} id
@return {boolean}
*/
recordIsLoaded: function(type, id) {
if (!this.hasRecordForId(type, id)) { return false; }
return !get(this.recordForId(type, id), 'isEmpty');
},
/**
This method returns the metadata for a specific type.
@method metadataFor
@param {String or subclass of DS.Model} type
@return {object}
*/
metadataFor: function(type) {
type = this.modelFor(type);
return this.typeMapFor(type).metadata;
},
// ............
// . UPDATING .
// ............
/**
If the adapter updates attributes or acknowledges creation
or deletion, the record will notify the store to update its
membership in any filters.
To avoid thrashing, this method is invoked only once per
run loop per record.
@method dataWasUpdated
@private
@param {Class} type
@param {DS.Model} record
*/
dataWasUpdated: function(type, record) {
this.recordArrayManager.recordDidChange(record);
},
// ..............
// . PERSISTING .
// ..............
/**
This method is called by `record.save`, and gets passed a
resolver for the promise that `record.save` returns.
It schedules saving to happen at the end of the run loop.
@method scheduleSave
@private
@param {DS.Model} record
@param {Resolver} resolver
*/
scheduleSave: function(record, resolver) {
record.adapterWillCommit();
this._pendingSave.push([record, resolver]);
once(this, 'flushPendingSave');
},
/**
This method is called at the end of the run loop, and
flushes any records passed into `scheduleSave`
@method flushPendingSave
@private
*/
flushPendingSave: function() {
var pending = this._pendingSave.slice();
this._pendingSave = [];
forEach(pending, function(tuple) {
var record = tuple[0], resolver = tuple[1];
var adapter = this.adapterFor(record.constructor);
var operation;
if (get(record, 'currentState.stateName') === 'root.deleted.saved') {
return resolver.resolve(record);
} else if (get(record, 'isNew')) {
operation = 'createRecord';
} else if (get(record, 'isDeleted')) {
operation = 'deleteRecord';
} else {
operation = 'updateRecord';
}
resolver.resolve(_commit(adapter, this, operation, record));
}, this);
},
/**
This method is called once the promise returned by an
adapter's `createRecord`, `updateRecord` or `deleteRecord`
is resolved.
If the data provides a server-generated ID, it will
update the record and the store's indexes.
@method didSaveRecord
@private
@param {DS.Model} record the in-flight record
@param {Object} data optional data (see above)
*/
didSaveRecord: function(record, data) {
if (data) {
// normalize relationship IDs into records
data = normalizeRelationships(this, record.constructor, data, record);
setupRelationships(this, record, data);
this.updateId(record, data);
}
record.adapterDidCommit(data);
},
/**
This method is called once the promise returned by an
adapter's `createRecord`, `updateRecord` or `deleteRecord`
is rejected with a `DS.InvalidError`.
@method recordWasInvalid
@private
@param {DS.Model} record
@param {Object} errors
*/
recordWasInvalid: function(record, errors) {
record.adapterDidInvalidate(errors);
},
/**
This method is called once the promise returned by an
adapter's `createRecord`, `updateRecord` or `deleteRecord`
is rejected (with anything other than a `DS.InvalidError`).
@method recordWasError
@private
@param {DS.Model} record
*/
recordWasError: function(record) {
record.adapterDidError();
},
/**
When an adapter's `createRecord`, `updateRecord` or `deleteRecord`
resolves with data, this method extracts the ID from the supplied
data.
@method updateId
@private
@param {DS.Model} record
@param {Object} data
*/
updateId: function(record, data) {
var oldId = get(record, 'id');
var id = coerceId(data.id);
Ember.assert("An adapter cannot assign a new id to a record that already has an id. " + record + " had id: " + oldId + " and you tried to update it with " + id + ". This likely happened because your server returned data in response to a find or update that had a different id than the one you sent.", oldId === null || id === oldId);
this.typeMapFor(record.constructor).idToRecord[id] = record;
set(record, 'id', id);
},
/**
Returns a map of IDs to client IDs for a given type.
@method typeMapFor
@private
@param {subclass of DS.Model} type
@return {Object} typeMap
*/
typeMapFor: function(type) {
var typeMaps = get(this, 'typeMaps');
var guid = Ember.guidFor(type);
var typeMap;
typeMap = typeMaps[guid];
if (typeMap) { return typeMap; }
typeMap = {
idToRecord: Object.create(null),
records: [],
metadata: Object.create(null),
type: type
};
typeMaps[guid] = typeMap;
return typeMap;
},
// ................
// . LOADING DATA .
// ................
/**
This internal method is used by `push`.
@method _load
@private
@param {String or subclass of DS.Model} type
@param {Object} data
*/
_load: function(type, data) {
var id = coerceId(data.id);
var record = this.recordForId(type, id);
record.setupData(data);
this.recordArrayManager.recordDidChange(record);
return record;
},
/**
Returns a model class for a particular key. Used by
methods that take a type key (like `find`, `createRecord`,
etc.)
@method modelFor
@param {String or subclass of DS.Model} key
@return {subclass of DS.Model}
*/
modelFor: function(key) {
var factory;
if (typeof key === 'string') {
factory = this.modelFactoryFor(key);
if (!factory) {
throw new Ember.Error("No model was found for '" + key + "'");
}
factory.typeKey = factory.typeKey || this._normalizeTypeKey(key);
} else {
// A factory already supplied. Ensure it has a normalized key.
factory = key;
if (factory.typeKey) {
factory.typeKey = this._normalizeTypeKey(factory.typeKey);
}
}
factory.store = this;
return factory;
},
modelFactoryFor: function(key){
return this.container.lookupFactory('model:' + key);
},
/**
Push some data for a given type into the store.
This method expects normalized data:
* The ID is a key named `id` (an ID is mandatory)
* The names of attributes are the ones you used in
your model's `DS.attr`s.
* Your relationships must be:
* represented as IDs or Arrays of IDs
* represented as model instances
* represented as URLs, under the `links` key
For this model:
```js
App.Person = DS.Model.extend({
firstName: DS.attr(),
lastName: DS.attr(),
children: DS.hasMany('person')
});
```
To represent the children as IDs:
```js
{
id: 1,
firstName: "Tom",
lastName: "Dale",
children: [1, 2, 3]
}
```
To represent the children relationship as a URL:
```js
{
id: 1,
firstName: "Tom",
lastName: "Dale",
links: {
children: "/people/1/children"
}
}
```
If you're streaming data or implementing an adapter,
make sure that you have converted the incoming data
into this form.
This method can be used both to push in brand new
records, as well as to update existing records.
@method push
@param {String or subclass of DS.Model} type
@param {Object} data
@return {DS.Model} the record that was created or
updated.
*/
push: function(typeName, data) {
Ember.assert("Expected an object as `data` in a call to `push` for " + typeName + " , but was " + data, Ember.typeOf(data) === 'object');
Ember.assert("You must include an `id` for " + typeName + " in an object passed to `push`", data.id != null && data.id !== '');
var type = this.modelFor(typeName);
// If the payload contains relationships that are specified as
// IDs, normalizeRelationships will convert them into DS.Model instances
// (possibly unloaded) before we push the payload into the
// store.
data = normalizeRelationships(this, type, data);
// Actually load the record into the store.
this._load(type, data);
var record = this.recordForId(type, data.id);
// Now that the pushed record as well as any related records
// are in the store, create the data structures used to track
// relationships.
setupRelationships(this, record, data);
return record;
},
/**
Push some raw data into the store.
This method can be used both to push in brand new
records, as well as to update existing records. You
can push in more than one type of object at once.
All objects should be in the format expected by the
serializer.
```js
App.ApplicationSerializer = DS.ActiveModelSerializer;
var pushData = {
posts: [
{id: 1, post_title: "Great post", comment_ids: [2]}
],
comments: [
{id: 2, comment_body: "Insightful comment"}
]
}
store.pushPayload(pushData);
```
By default, the data will be deserialized using a default
serializer (the application serializer if it exists).
Alternatively, `pushPayload` will accept a model type which
will determine which serializer will process the payload.
However, the serializer itself (processing this data via
`normalizePayload`) will not know which model it is
deserializing.
```js
App.ApplicationSerializer = DS.ActiveModelSerializer;
App.PostSerializer = DS.JSONSerializer;
store.pushPayload('comment', pushData); // Will use the ApplicationSerializer
store.pushPayload('post', pushData); // Will use the PostSerializer
```
@method pushPayload
@param {String} type Optionally, a model used to determine which serializer will be used
@param {Object} payload
*/
pushPayload: function (type, inputPayload) {
var serializer;
var payload;
if (!inputPayload) {
payload = type;
serializer = defaultSerializer(this.container);
Ember.assert("You cannot use `store#pushPayload` without a type unless your default serializer defines `pushPayload`", serializer.pushPayload);
} else {
payload = inputPayload;
serializer = this.serializerFor(type);
}
serializer.pushPayload(this, payload);
},
/**
`normalize` converts a json payload into the normalized form that
[push](#method_push) expects.
Example
```js
socket.on('message', function(message) {
var modelName = message.model;
var data = message.data;
store.push(modelName, store.normalize(modelName, data));
});
```
@method normalize
@param {String} type The name of the model type for this payload
@param {Object} payload
@return {Object} The normalized payload
*/
normalize: function (type, payload) {
var serializer = this.serializerFor(type);
var model = this.modelFor(type);
return serializer.normalize(model, payload);
},
/**
Update existing records in the store. Unlike [push](#method_push),
update will merge the new data properties with the existing
properties. This makes it safe to use with a subset of record
attributes. This method expects normalized data.
`update` is useful if your app broadcasts partial updates to
records.
```js
App.Person = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string')
});
store.get('person', 1).then(function(tom) {
tom.get('firstName'); // Tom
tom.get('lastName'); // Dale
var updateEvent = {id: 1, firstName: "TomHuda"};
store.update('person', updateEvent);
tom.get('firstName'); // TomHuda
tom.get('lastName'); // Dale
});
```
@method update
@param {String} type
@param {Object} data
@return {DS.Model} the record that was updated.
@deprecated Use `push` instead
*/
update: function(type, data) {
Ember.deprecate('Using store.update() has been deprecated since store.push() now handles partial updates. You should use store.push() instead.');
return this.push(type, data);
},
/**
If you have an Array of normalized data to push,
you can call `pushMany` with the Array, and it will
call `push` repeatedly for you.
@method pushMany
@param {String or subclass of DS.Model} type
@param {Array} datas
@return {Array}
*/
pushMany: function(type, datas) {
var length = datas.length;
var result = new Array(length);
for (var i = 0; i < length; i++) {
result[i] = this.push(type, datas[i]);
}
return result;
},
/**
If you have some metadata to set for a type
you can call `metaForType`.
@method metaForType
@param {String or subclass of DS.Model} type
@param {Object} metadata
*/
metaForType: function(typeName, metadata) {
var type = this.modelFor(typeName);
Ember.merge(this.typeMapFor(type).metadata, metadata);
},
/**
Build a brand new record for a given type, ID, and
initial data.
@method buildRecord
@private
@param {subclass of DS.Model} type
@param {String} id
@param {Object} data
@return {DS.Model} record
*/
buildRecord: function(type, id, data) {
var typeMap = this.typeMapFor(type);
var idToRecord = typeMap.idToRecord;
Ember.assert('The id ' + id + ' has already been used with another record of type ' + type.toString() + '.', !id || !idToRecord[id]);
Ember.assert("`" + Ember.inspect(type)+ "` does not appear to be an ember-data model", (typeof type._create === 'function') );
// lookupFactory should really return an object that creates
// instances with the injections applied
var record = type._create({
id: id,
store: this,
container: this.container
});
if (data) {
record.setupData(data);
}
// if we're creating an item, this process will be done
// later, once the object has been persisted.
if (id) {
idToRecord[id] = record;
}
typeMap.records.push(record);
return record;
},
// ...............
// . DESTRUCTION .
// ...............
/**
When a record is destroyed, this un-indexes it and
removes it from any record arrays so it can be GCed.
@method dematerializeRecord
@private
@param {DS.Model} record
*/
dematerializeRecord: function(record) {
var type = record.constructor;
var typeMap = this.typeMapFor(type);
var id = get(record, 'id');
record.updateRecordArrays();
if (id) {
delete typeMap.idToRecord[id];
}
var loc = indexOf(typeMap.records, record);
typeMap.records.splice(loc, 1);
},
// ......................
// . PER-TYPE ADAPTERS
// ......................
/**
Returns the adapter for a given type.
@method adapterFor
@private
@param {subclass of DS.Model} type
@return DS.Adapter
*/
adapterFor: function(type) {
var container = this.container, adapter;
if (container) {
adapter = container.lookup('adapter:' + type.typeKey) || container.lookup('adapter:application');
}
return adapter || get(this, 'defaultAdapter');
},
// ..............................
// . RECORD CHANGE NOTIFICATION .
// ..............................
/**
Returns an instance of the serializer for a given type. For
example, `serializerFor('person')` will return an instance of
`App.PersonSerializer`.
If no `App.PersonSerializer` is found, this method will look
for an `App.ApplicationSerializer` (the default serializer for
your entire application).
If no `App.ApplicationSerializer` is found, it will fall back
to an instance of `DS.JSONSerializer`.
@method serializerFor
@private
@param {String} type the record to serialize
@return {DS.Serializer}
*/
serializerFor: function(type) {
type = this.modelFor(type);
var adapter = this.adapterFor(type);
return serializerFor(this.container, type.typeKey, adapter && adapter.defaultSerializer);
},
willDestroy: function() {
var typeMaps = this.typeMaps;
var keys = Ember.keys(typeMaps);
var types = map(keys, byType);
this.recordArrayManager.destroy();
forEach(types, this.unloadAll, this);
function byType(entry) {
return typeMaps[entry]['type'];
}
},
/**
All typeKeys are camelCase internally. Changing this function may
require changes to other normalization hooks (such as typeForRoot).
@method _normalizeTypeKey
@private
@param {String} type
@return {String} if the adapter can generate one, an ID
*/
_normalizeTypeKey: function(key) {
return camelize(singularize(key));
}
});
function normalizeRelationships(store, type, data, record) {
type.eachRelationship(function(key, relationship) {
var kind = relationship.kind;
var value = data[key];
if (kind === 'belongsTo') {
deserializeRecordId(store, data, key, relationship, value);
} else if (kind === 'hasMany') {
deserializeRecordIds(store, data, key, relationship, value);
}
});
return data;
}
function deserializeRecordId(store, data, key, relationship, id) {
if (!Model) { Model = requireModule("ember-data/system/model")["Model"]; }
if (isNone(id) || id instanceof Model) {
return;
}
Ember.assert("A " + relationship.parentType + " record was pushed into the store with the value of " + key + " being " + Ember.inspect(id) + ", but " + key + " is a belongsTo relationship so the value must not be an array. You should probably check your data payload or serializer.", !Ember.isArray(id));
var type;
if (typeof id === 'number' || typeof id === 'string') {
type = typeFor(relationship, key, data);
data[key] = store.recordForId(type, id);
} else if (typeof id === 'object') {
// polymorphic
data[key] = store.recordForId(id.type, id.id);
}
}
function typeFor(relationship, key, data) {
if (relationship.options.polymorphic) {
return data[key + "Type"];
} else {
return relationship.type;
}
}
function deserializeRecordIds(store, data, key, relationship, ids) {
if (isNone(ids)) {
return;
}
Ember.assert("A " + relationship.parentType + " record was pushed into the store with the value of " + key + " being '" + Ember.inspect(ids) + "', but " + key + " is a hasMany relationship so the value must be an array. You should probably check your data payload or serializer.", Ember.isArray(ids));
for (var i=0, l=ids.length; i<l; i++) {
deserializeRecordId(store, ids, i, relationship, ids[i]);
}
}
// Delegation to the adapter and promise management
function serializerFor(container, type, defaultSerializer) {
return container.lookup('serializer:'+type) ||
container.lookup('serializer:application') ||
container.lookup('serializer:' + defaultSerializer) ||
container.lookup('serializer:-default');
}
function defaultSerializer(container) {
return container.lookup('serializer:application') ||
container.lookup('serializer:-default');
}
function serializerForAdapter(adapter, type) {
var serializer = adapter.serializer;
var defaultSerializer = adapter.defaultSerializer;
var container = adapter.container;
if (container && serializer === undefined) {
serializer = serializerFor(container, type.typeKey, defaultSerializer);
}
if (serializer === null || serializer === undefined) {
serializer = {
extract: function(store, type, payload) { return payload; }
};
}
return serializer;
}
function _objectIsAlive(object) {
return !(get(object, "isDestroyed") || get(object, "isDestroying"));
}
function _guard(promise, test) {
var guarded = promise['finally'](function() {
if (!test()) {
guarded._subscribers.length = 0;
}
});
return guarded;
}
function _bind(fn) {
var args = Array.prototype.slice.call(arguments, 1);
return function() {
return fn.apply(undefined, args);
};
}
function _find(adapter, store, type, id, record) {
var promise = adapter.find(store, type, id, record);
var serializer = serializerForAdapter(adapter, type);
var label = "DS: Handle Adapter#find of " + type + " with id: " + id;
promise = Promise.cast(promise, label);
promise = _guard(promise, _bind(_objectIsAlive, store));
return promise.then(function(adapterPayload) {
Ember.assert("You made a request for a " + type.typeKey + " with id " + id + ", but the adapter's response did not have any data", adapterPayload);
var payload = serializer.extract(store, type, adapterPayload, id, 'find');
return store.push(type, payload);
}, function(error) {
var record = store.getById(type, id);
if (record) {
record.notFound();
}
throw error;
}, "DS: Extract payload of '" + type + "'");
}
function _findMany(adapter, store, type, ids, records) {
var promise = adapter.findMany(store, type, ids, records);
var serializer = serializerForAdapter(adapter, type);
var label = "DS: Handle Adapter#findMany of " + type;
if (promise === undefined) {
throw new Error('adapter.findMany returned undefined, this was very likely a mistake');
}
promise = Promise.cast(promise, label);
promise = _guard(promise, _bind(_objectIsAlive, store));
return promise.then(function(adapterPayload) {
var payload = serializer.extract(store, type, adapterPayload, null, 'findMany');
Ember.assert("The response from a findMany must be an Array, not " + Ember.inspect(payload), Ember.typeOf(payload) === 'array');
return store.pushMany(type, payload);
}, null, "DS: Extract payload of " + type);
}
function _findHasMany(adapter, store, record, link, relationship) {
var promise = adapter.findHasMany(store, record, link, relationship);
var serializer = serializerForAdapter(adapter, relationship.type);
var label = "DS: Handle Adapter#findHasMany of " + record + " : " + relationship.type;
promise = Promise.cast(promise, label);
promise = _guard(promise, _bind(_objectIsAlive, store));
promise = _guard(promise, _bind(_objectIsAlive, record));
return promise.then(function(adapterPayload) {
var payload = serializer.extract(store, relationship.type, adapterPayload, null, 'findHasMany');
Ember.assert("The response from a findHasMany must be an Array, not " + Ember.inspect(payload), Ember.typeOf(payload) === 'array');
var records = store.pushMany(relationship.type, payload);
return records;
}, null, "DS: Extract payload of " + record + " : hasMany " + relationship.type);
}
function _findBelongsTo(adapter, store, record, link, relationship) {
var promise = adapter.findBelongsTo(store, record, link, relationship);
var serializer = serializerForAdapter(adapter, relationship.type);
var label = "DS: Handle Adapter#findBelongsTo of " + record + " : " + relationship.type;
promise = Promise.cast(promise, label);
promise = _guard(promise, _bind(_objectIsAlive, store));
promise = _guard(promise, _bind(_objectIsAlive, record));
return promise.then(function(adapterPayload) {
var payload = serializer.extract(store, relationship.type, adapterPayload, null, 'findBelongsTo');
var record = store.push(relationship.type, payload);
return record;
}, null, "DS: Extract payload of " + record + " : " + relationship.type);
}
function _findAll(adapter, store, type, sinceToken) {
var promise = adapter.findAll(store, type, sinceToken);
var serializer = serializerForAdapter(adapter, type);
var label = "DS: Handle Adapter#findAll of " + type;
promise = Promise.cast(promise, label);
promise = _guard(promise, _bind(_objectIsAlive, store));
return promise.then(function(adapterPayload) {
var payload = serializer.extract(store, type, adapterPayload, null, 'findAll');
Ember.assert("The response from a findAll must be an Array, not " + Ember.inspect(payload), Ember.typeOf(payload) === 'array');
store.pushMany(type, payload);
store.didUpdateAll(type);
return store.all(type);
}, null, "DS: Extract payload of findAll " + type);
}
function _findQuery(adapter, store, type, query, recordArray) {
var promise = adapter.findQuery(store, type, query, recordArray);
var serializer = serializerForAdapter(adapter, type);
var label = "DS: Handle Adapter#findQuery of " + type;
promise = Promise.cast(promise, label);
promise = _guard(promise, _bind(_objectIsAlive, store));
return promise.then(function(adapterPayload) {
var payload = serializer.extract(store, type, adapterPayload, null, 'findQuery');
Ember.assert("The response from a findQuery must be an Array, not " + Ember.inspect(payload), Ember.typeOf(payload) === 'array');
recordArray.load(payload);
return recordArray;
}, null, "DS: Extract payload of findQuery " + type);
}
function _commit(adapter, store, operation, record) {
var type = record.constructor;
var promise = adapter[operation](store, type, record);
var serializer = serializerForAdapter(adapter, type);
var label = "DS: Extract and notify about " + operation + " completion of " + record;
Ember.assert("Your adapter's '" + operation + "' method must return a value, but it returned `undefined", promise !==undefined);
promise = Promise.cast(promise, label);
promise = _guard(promise, _bind(_objectIsAlive, store));
promise = _guard(promise, _bind(_objectIsAlive, record));
return promise.then(function(adapterPayload) {
var payload;
if (adapterPayload) {
payload = serializer.extract(store, type, adapterPayload, get(record, 'id'), operation);
} else {
payload = adapterPayload;
}
store.didSaveRecord(record, payload);
return record;
}, function(reason) {
if (reason instanceof InvalidError) {
var errors = serializer.extractErrors(store, type, reason.errors, get(record, 'id'));
store.recordWasInvalid(record, errors);
reason = new InvalidError(errors);
} else {
store.recordWasError(record, reason);
}
throw reason;
}, label);
}
function setupRelationships(store, record, data) {
var type = record.constructor;
type.eachRelationship(function(key, descriptor) {
var kind = descriptor.kind;
var value = data[key];
var relationship = record._relationships[key];
if (data.links && data.links[key]) {
relationship.updateLink(data.links[key]);
}
if (kind === 'belongsTo') {
if (value === undefined) {
return;
}
relationship.setRecord(value);
} else if (kind === 'hasMany' && value) {
relationship.updateRecordsFromAdapter(value);
}
});
}
export { Store };
export default Store;