2014-06-30 22:16:26 -04:00
mongoose = require ' mongoose '
jsonschema = require ' ../../app/schemas/models/achievement '
2014-05-21 13:47:17 -04:00
log = require ' winston '
2014-11-28 20:49:41 -05:00
utils = require ' ../../app/core/utils '
2014-06-09 11:28:35 -04:00
plugins = require ( ' ../plugins/plugins ' )
2014-06-13 12:04:25 -04:00
AchievablePlugin = require ' ../plugins/achievements '
2014-08-29 15:41:25 -04:00
TreemaUtils = require ' ../../bower_components/treema/treema-utils.js '
2014-05-13 16:46:56 -04:00
# `pre` and `post` are not called for update operations executed directly on the database,
# including `Model.update`,`.findByIdAndUpdate`,`.findOneAndUpdate`, `.findOneAndRemove`,and `.findByIdAndRemove`.order
# to utilize `pre` or `post` middleware, you should `find()` the document, and call the `init`, `validate`, `save`,
# or `remove` functions on the document. See [explanation](http://github.com/LearnBoost/mongoose/issues/964).
AchievementSchema = new mongoose . Schema ( {
2014-05-21 13:47:17 -04:00
userField: String
2015-03-20 16:33:03 -04:00
} , { strict: false , read : ' nearest ' } )
2014-05-13 16:46:56 -04:00
2015-01-27 13:02:47 -05:00
AchievementSchema . index (
{
_fts: ' text '
_ftsx: 1
} ,
{
name: ' search index '
sparse: true
weights: { name: 1 }
default_language: ' english '
' language_override ' : ' language '
' textIndexVersion ' : 2
} )
AchievementSchema . index ( { i18nCoverage: 1 } , { name: ' translation coverage index ' , sparse: true } )
AchievementSchema . index ( { slug: 1 } , { name: ' slug index ' , sparse: true , unique: true } )
2014-06-03 06:40:47 -04:00
AchievementSchema.methods.objectifyQuery = ->
2014-05-21 13:47:17 -04:00
try
2014-06-30 22:16:26 -04:00
@ set ( ' query ' , JSON . parse ( @ get ( ' query ' ) ) ) if typeof @ get ( ' query ' ) == ' string '
2014-05-21 13:47:17 -04:00
catch error
2014-05-24 14:45:53 -04:00
log . error " Couldn ' t convert query string to object because of #{ error } "
2014-05-21 13:47:17 -04:00
@ set ( ' query ' , { } )
2014-06-03 06:40:47 -04:00
AchievementSchema.methods.stringifyQuery = ->
2014-06-30 22:16:26 -04:00
@ set ( ' query ' , JSON . stringify ( @ get ( ' query ' ) ) ) if typeof @ get ( ' query ' ) != ' string '
2014-05-21 13:47:17 -04:00
2014-06-14 09:34:23 -04:00
AchievementSchema.methods.getExpFunction = ->
2014-08-29 15:41:25 -04:00
func = @ get ( ' function ' ) ? { }
TreemaUtils . populateDefaults ( func , jsonschema . properties . function )
return utils . functionCreators [ func . kind ] ( func . parameters ) if func . kind of utils . functionCreators
2014-06-03 06:40:47 -04:00
2014-06-14 14:12:17 -04:00
AchievementSchema.statics.jsonschema = jsonschema
2015-02-13 20:10:30 -05:00
AchievementSchema.statics.achievementCollections = { }
2014-06-14 09:34:23 -04:00
2014-06-24 07:49:54 -04:00
# Reloads all achievements into memory.
# TODO might want to tweak this to only load new achievements
2014-06-14 09:34:23 -04:00
AchievementSchema.statics.loadAchievements = (done) ->
AchievementSchema . statics . resetAchievements ( )
Achievement = require ( ' ../achievements/Achievement ' )
2014-11-21 01:08:49 -05:00
query = Achievement . find ( { collection: { $ne: ' level.sessions ' } } )
2014-06-14 09:34:23 -04:00
query . exec (err, docs) ->
_ . each docs , (achievement) ->
2015-02-13 20:10:30 -05:00
collection = achievement . get ' collection '
AchievementSchema . statics . achievementCollections [ collection ] ? = [ ]
if _ . find AchievementSchema . statics . achievementCollections [ collection ] , ( (a) -> a . get ( ' _id ' ) . toHexString ( ) is achievement . get ( ' _id ' ) . toHexString ( ) )
log . warn " Uh oh, we tried to add another copy of the same achievement #{ achievement . get ( ' _id ' ) } #{ achievement . get ( ' name ' ) } to the #{ collection } achievement list... "
2015-02-13 19:33:03 -05:00
else
2015-02-13 20:10:30 -05:00
AchievementSchema . statics . achievementCollections [ collection ] . push achievement
2015-02-13 19:33:03 -05:00
unless achievement . get ( ' query ' )
log . error " Uh oh, there is an achievement with an empty query: #{ achievement } "
2015-02-13 20:10:30 -05:00
done ? ( AchievementSchema . statics . achievementCollections )
2014-06-14 09:34:23 -04:00
AchievementSchema.statics.getLoadedAchievements = ->
2015-02-13 20:10:30 -05:00
AchievementSchema . statics . achievementCollections
2014-06-14 09:34:23 -04:00
AchievementSchema.statics.resetAchievements = ->
2015-02-13 20:10:30 -05:00
delete AchievementSchema . statics . achievementCollections [ collection ] for collection of AchievementSchema . statics . achievementCollections
2014-06-14 09:34:23 -04:00
2014-06-24 07:49:54 -04:00
# Queries are stored as JSON strings, objectify them upon loading
2014-06-13 12:04:25 -04:00
AchievementSchema . post ' init ' , (doc) -> doc . objectifyQuery ( )
2014-05-21 13:47:17 -04:00
2014-06-13 12:04:25 -04:00
AchievementSchema . pre ' save ' , (next) ->
2014-05-21 13:47:17 -04:00
@ stringifyQuery ( )
next ( )
2014-06-13 12:04:25 -04:00
# Reload achievements upon save
2015-02-13 19:33:03 -05:00
# This is going to basically not work when there is more than one application server, right?
2014-06-14 09:34:23 -04:00
AchievementSchema . post ' save ' , -> @ constructor . loadAchievements ( )
2014-05-21 13:47:17 -04:00
2014-05-19 17:20:50 -04:00
AchievementSchema . plugin ( plugins . NamedPlugin )
2014-05-31 17:19:55 -04:00
AchievementSchema . plugin ( plugins . SearchablePlugin , { searchable: [ ' name ' ] } )
2014-10-27 20:11:48 -04:00
AchievementSchema . plugin plugins . TranslationCoveragePlugin
2015-02-05 15:01:19 -05:00
AchievementSchema . plugin plugins . PatchablePlugin
2014-06-09 11:28:35 -04:00
2014-07-03 15:20:06 -04:00
module.exports = Achievement = mongoose . model ( ' Achievement ' , AchievementSchema , ' achievements ' )
2014-06-10 14:05:32 -04:00
2014-06-14 09:34:23 -04:00
AchievementSchema . statics . loadAchievements ( )