def createOrUpdate(wave_id, wavelet_id, participant_profiles=None):
    '''
    Creates or updates a followed wave and wave meta object
    @param wave_id: the id of the wave these records are for
    @param wavelet_id: the id of the wavelet these records are for
    @param participant_profiles=None: the participant profiles for this wave
    '''
    #Fetch or create
    waveMeta = get(wave_id, wavelet_id)
    if not waveMeta:
        followedWave = FollowedWave(wave_id     =   wave_id,
                                    wavelet_id  =   wavelet_id,
                                    key_name    =   _generateFollowedWaveKey(   wave_id,
                                                                                wavelet_id))
        _putFollowedWave(followedWave)
        waveMeta = WaveMeta(parent = followedWave)
    
    if participant_profiles:
        waveMeta.participant_profiles = participant_profiles
    
    put(waveMeta, wave_id, wavelet_id)
def _getWaveMeta(followedWave):
    '''
    Returns a wave meta instance if it can be found in the datastore or 
    memcache
    @transaction_safe
    @param followedWave: the parent followedWave instance
    @return the WaveMeta instance or None if it was not found
    '''
    key = base64.b64encode( memcacheConfig.PREFIX['WAVE_META'] + 
                            followedWave.wave_id +
                            followedWave.wavelet_id)
    waveMeta = memcache.get(key)
    if not waveMeta == None:
        return waveMeta
    else:
        query = WaveMeta.all()
        query.ancestor(followedWave)
        waveMeta = query.get()
        memcache.add(key, waveMeta, time=memcacheConfig.DEFAULT_EXPIRE_SECS)
        return waveMeta