This page provides information about how a future team might go about migrating our model tier
code to another style of database.

- **Author**: Alex Wilkes <[adw4236@rit.edu](mailto:adw4236@rit.edu)>

# Database Migration
Our model tier is rooted in the idea of mapping database entries to JSON objects as well as providing
some methods on those objects that can be used to adjust the objects.  No matter the database
implementation, this core principle can still be followed.  The only thing that should need to
change during migration is the backing framework and the model tier method implementations.

An afterthought the team had is that it might be worth it to avoid using mongoose methods outside
of the model tier to make this transition easier.  If the future team think this is worthwhile, it
will be easier to remove all occurrences of those methods sooner than later.

## CosmosDB to Other NoSQL Database
Depending on the NoSQL database, this should be a practically seamless transition.  Other cloud
platforms like Azure have their own version of CosmosDB that can run on the MongoDB API.  If it
is any other type of NoSQL implementation, this will really depend on the specific one.  Most
NoSQL databases should however have a reasonable npm package that can be used to interface with
them.

## Migration to SQL Database
Migrating to an SQL database is a bit harder, but there are two design choices that will make the
transition very doable.  We have also maintained the position of having a strict schema even though
mongoose allows more flexibility for this exact reason.

The first choice would be to go with an Object Relational Mapper.  While these are very popular
with strictly OO languages like Java, they may not be the best choice for Node environments.
That being said, they should do almost the exact same thing as mongoose and allow you to re-create
these objects 1 for 1, so they can be used by any other tiers in the exact same way.

If a future team is switching to SQL however, the most likely reason for that is speed, in which
case an ORM may not be a tradeoff they are willing to make.  In this situation, it may be more apt
to have all custom static methods return an object that is not directly mapped to the database, but
rather has the same methods which have the ability to make calls to the database in whatever method
deemed necessary.

For example in `skill.js`:

```javascript
function getSkill(id){

  // Make database call however you need to to receive data

  return {
    name,
    description,
    // ... non-static methods would also go here.
  }
}

module.exports = {
  findOneOrCreate(name){
    // Query database however you need to
    // Find the id associated with the given name
    return getSkill(id);
  },
  // ... other static methods
}
```

You can even use the [defineProperties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties)
API to intercept calls to setting parameters if needed.

This will overall require quite a bit more work (and more thought than has been given here) than the ORM,
but is still a perfectly valid choice that should not require re-writing any code in other tiers.