Giter Site home page Giter Site logo

phpmig's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

phpmig's Issues

SQL error propagation and abort migration

Hello, thank you for the phpmig, I've been using it for some time in my oss and not projects and find it just wonderful!

One thing that happens to me quite often is to right down the sql migration that doesn't work :) I mean it generates the database error (plenty of reasons: syntax, FK, constrains, triggers etc) but the error disappears somehow so that you need to run one migration at a time to be sure it is done correctly and you may proceed with the next one.

Am I missing something? Could it be done so that the error will break the migration and stops all scripts leaving the database in the state right before the error happened? Should it yet to be done and can I help? Could it be included the whole migration in one transaction?

My try to use the phpmig you may find here: https://github.com/moiseevigor/onelife-slim/tree/master/db

Thank you again,
Igor.

Missing Adapter\PDO\Sql.php

Hi Dave,

It appears that the PDO Sql adapter file is missing from the composer install. I patched my instance from your repo and got it working but I guess it's an easy fix to the composer lib.

Dave

Simplify access to db instance

Why always duplicate these lines:

$c = $this->getContainer();
$c['db']->query();

Maybe it would be better to have some property in the migration class to access to $container['db'] ?
Like $this->db->query()

As far as I know, typically the Migration class itself has method wrappers for accessing DB and usually it looks like $this->createTable() or $this->exec inside of migration.

What do you think about it?

migrations path

I think in most case migrations files are in one place, and only in one place.
So why don't permit to set this path instead of an array of files in the bootstrap ?

I see to solution :

  • the first one is to set phpmig.migrations as a string (the dirstory path) and assume that all files are extended by .php ( because they are generated by phpmig whith this extension ) than in abstractCommand test if phpmig is an array of files or a path to the directory.
  • the second one is to set an other key, something likes phpmig.migrations_path

What do you think of that ?

Callback during migration

I'm thinking of adding callback support to the migration process. This would be especially useful in the API migration.

Why?
There's no feedback during migration processing. This can leave users feeling as if the app has stalled when processing a significant number of migrations.

A callback that is executed after each migration is processed would allow feedback to be presented to the user on the progress.

Thoughts?

Undocumented usage of `container.sets`

I have been very busy but am still working on the refactor PR but I just wanted to make sure I fully understood what this set parameter is for. As far as I know, it seems to be undocumented. I have seen it in multiple places but here is one just to illustrate what I am referring to. Is it just so you can have different sets of standalone migrations?

Just wanted to make sure I fully understood the intent so I can make sure to not break existing functionality.

Allow out of order migrations

One huge improvement to migration handling when you're dealing with pull requests which may be merged out of order is the ability to run migrations out of order.

What does that mean exactly? It means finding and sorting all migrations which exist but have not been processed, then processing those migrations (in order).

For example. Assume we have the following migrations in our database

version
20160314000000
20160315000000
20160316000000

Now suppose we merge a new migration in. It's called 20160315060000_SomeTask.php. We can't run it. Instead we have to rollback to 20160315000000, then migrate forward again. This is a huge pain.

With a setting (disabled by default) allowing any migration to be processed that hasn't been processed we'd have:

version
20160314000000
20160315000000
20160316000000
20160315060000

Issue with OSX

I am hading a difficult time getting this to work on my OSX environment. I can cd into the bin dir but when I run $ php phpmig migrate it does nothing but show me the output of the Cygwin check.

Compatibility?

The readme suggests installing Pimple for a quick bootstrap however I think Pimple has been evolving and having more releases than that of phpmig.

As far as I've tested the compatibility for the bootstraped phpmig it only works with Pimple 1.1, is this correct? If so would be nice for either the documentation or the composer.json to have it.

transaction and migrations with error

This package looks promising, but I've found something problematic. The migrations don't care about errors. It would be nice a safeUp method with transaction handling. If there is a migration with error, then don't migrate it.

Container not available in init() function

When using the following code in my migration script, getContainer returns null.

protected function init()
{
    $container = $this->getContainer();
    var_dump($container);
}

My current solution is extending Migration and make a call to setup.

use Phpmig\Migration\Migration as Phpmig;

class Migration extends Phpmig
{
    /**
     * Called after the container is injected.
     *
     * @return void
     */
    public function setup()
    {
        return;
    }

    public function setContainer(\ArrayAccess $container)
    {
        parent::setContainer($container);
        $this->setup();

        return $this;
    }
}

The Container could also be injected into the constructor and set before init is being called, but I didn't want to start a fork for this tiny issue.

Offtopic: Is this project still active? Will it ever reach a stable version? Do you accept pull requests?

phpmig.php broke

Seems there was an undocumented BC, my phpmig.php simply contained 'migrations_path'.

(I'm not sure from wich version I was upgrading)

The current version I'm using is 0.4.0.

And the error I got:
[...]/phpmig.php must return container with array at phpmig.migrations

Took me a while to find it, because it is not mentioned here:
https://github.com/davedevelopment/phpmig/blob/master/CHANGELOG.md

Fixed it by adding:

// phpmig.php
$c['phpmig.migrations'] = $c->share(function() use ($c) {
    return glob($c['phpmig.migrations_path'] . '/*.php');
});

Submodule migrations

This is more of a feature idea.

My projects are made up of a bunch of modules. It would be good if each module could keep its own migrations, but run them as part of an application.

For example I have this directory structure:

    project
    ¦   phpmig.php
    +---migrations
    +---modules
    ¦   +---cms
    ¦   ¦   +---migrations
    ¦   +---email
    ¦       +---migrations
    +---public
        ¦   index.php
        +---images
                etc...

Running phpmig on the project directory should run all migrations, including ones in sub modules.

There would be of course problems with the current logging format and DI containers. The logging of migrations that have been run would need to be stored in the project log file/DB. And each sub module would have to have a compatible DI object for accessing the database.

The log file (I haven't used DB logging) could be adapted like so:

    20111100133144
    20111100721245
    modules/cms/2011110054613
    modules/cms/2011110014658
    modules/email/2011110016455

I'm happy to implement this, what are you thoughts?

The version column of migrations table is to small to a version number.

I'm using Doctrine DBAL and MySql, and it creates a migrations table.But the version column int (10) is too small to a version number. When a version number like 20120628200012 insert into migrations table,MySql will convert it to 4294967295.
After I change the version column type to bigint, It works fine.

move to phpmig organization

How about moving phpmig into phpmig organization, and separate main project from adapters?
I'd like to see packages named as:

  • phpmig/phpmig
  • phpmig/doctrine-adapter
  • phpmig/eloquent-adapter

I will also move bitrix adapter into organization.

migrate error

when I run phpmig , error railsed mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead

can you help me ?

Update README.md to reflect stable release

There are 2 parts in README.md file that should be updated since 1.0.0 release:

  • part with * as version constraint for Composer
  • part that says that API isn't stable because no stable release was made

This looks great

I just wanted to give you a thumbs up! This is gonna be great!

ability to access service locator?

I see that the readme uses Zend's autoloader. Is there any way to have access to the servicelocator from within the up() and down() methods?

Running migrations via API

Wondering if this is the proper way to invoke migrations via the API as opposed to the CLI? Also, would this run all migrations up to the latest version, or does Migrator::up() have to be invoked once per version?

<?php
$container = include "path/to/phpmig.php";

use Phpmig\Migration;
use Symfony\Component\Console\Output;

$latest_version = "20141027000000";
$migration = new Migration($latest_version);
$output = new BufferedOutput();
$container['phpmig.migrator'] = new Migrator($container['phpmig.adapter'], $container, $output);
$container['phpmig.migrator']->up($migration);

var_dump($output->fetch());

Same migrations on different databases

In a project of mine I'm planning to:

  • store VCS revision info (commit_id, files changed, etc.) in an SQLite database
  • there would be separate SQLite database per repository (easier, than having to add "repository_id" column to each table)
  • have single set of migration scripts (via this library)

What I'm struggling at is how to make it all work considering, that:

  • I don't know SQLite database location at the moment, when PHPMig library is initialized and therefore:
    • I can't use PHPMig CLI to create new migrations easily
    • I can't specify any DB in PHPMig config to create "migration" table in

Here is how I plan this to work: I call a method in my code like this ...->getDatabase('/path/to/db1.sqlite'); and will:

  • if database is missing, then:
    • create an empty file
    • populate it with proper empty tables
    • return PDO class object
  • if file is present, then:
    • open it
    • execute missing migrations (if any)
    • return PDO class object

Bootstrap file

Another feature for thought.

Instead of having a default php bootstrap file called phpmig.php, perhaps a configuration file would be better, such as .phpmig

A few reasons for this would be:

  • phpmig.php cannot be run standalone, and throws errors
  • phpmig.php is accessible (by default) with Apache (.phpmig would not be)
  • .phpmig could point to an appropriate bootstrap (or even multiple php files to be run)
  • .phpmig could point to the migrations directory
  • .phpmig would be more easily extendable to add extra properties in the future

The .phpmig format could be as simple as an INI, or perhaps even YAML, JSON, or XML

Can I rollback last migration?

I tried using down() method with version number but it's not work! I changed PhpmigApplication.php file

from

// down
} elseif ($to < $from && $version > $to && $version <= $from) {
   $migrations[] = $path;
}

to

// down
} elseif ($to <= $from && $version => $to && $version <= $from) {
   $migrations[] = $path;
}

Then, I call down() method with version number it's rollback last migration. Anyone here who can help me??

Ask user before rollback

Wouldn't it be better to ask user if he really wants to rollback database when not in quiet mode?

Usually rollback is irreversable, thus accidental data loss could happen.

Problem with rollback

There's some major issue in rollback command. I've created migration and run migrate command - three times. After running rollback commad, all records from migrations table was deleted, but only last migration was rolled back.
To fix this issue, you need to change down method in Db class and set as array key this 'version = ?' instead of this 'version'

namespacing migrations

It doesn't appear that we can currently namespace our migrations. Here's why it would be good to have:

  1. Prevents polluting global namespace.
  2. Avoids collisions with other migrations a la #9.
  3. Allows migrations to pass PSR-2 style checks.

To accomplish this we'd need the ability to specify the namespace for each collection of migrations so they can be loaded correctly.

Thoughts?

phpmig and capistrano

I'm looking to a way to handle database rollback on capistrano rollback.
One off the solution that I'm seeing is to dump migrations done in a file after each deploy.
Like that on rollback I could do a diff and rollback the newest migrations.

What do you think about that ?

Capistrano being a common deployement tools, what do you think about integrate capistrano's helper in phpmig ?

Laravel adapter fetchAll not working

Commit 0f3725a breaks Laravel's adapter.

table() function returns an instance of Query\Builder so the get() returns an array not a Collection, so after this commit this package is broken for Laravel. The toArray() function is only available for the Eloquent Builder as the Eloquent one returns a collection.

PHP Fatal error: Call to a member function toArray() on a non-object in vendor/davedevelopment/phpmig/src/Phpmig/Adapter/Illuminate/Database.php on line 47

Adding phpmig to app commands

I wanted to add phpmig to my app console entry point.
So I Wrote something like that :

use Phpmig\Console\Command;

$app = new Symfony\Component\Console\Application();

$phpmig_commands = [
    new Command\InitCommand(),
    new Command\StatusCommand(),
    new Command\CheckCommand(),
    new Command\GenerateCommand(),
    new Command\UpCommand(),
    new Command\DownCommand(),
    new Command\MigrateCommand(),
    new Command\RollbackCommand()
];
foreach($phpmig_commands as $command) {
    $command->setName('phpmig:'.$command->getName());
}

$app->addCommands($phpmig_commands);

$app->run();

That makes the job, but I've some issue with the configuration loading, maybe we can found a way to add phpmig commands to application commands and giving it the configuration by the same way.

For exemple :

use \Phpmig\Adapter,
    \Pimple;

$container = new Pimple();

$container['db'] = $container->share(function() {
    $dbh = new PDO('mysql:dbname=testdb;host=127.0.0.1','username','passwd');
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    return $dbh;
});

$container['phpmig.adapter'] = $container->share(function() use ($container) {
    return new Adapter\PDO\Sql($container['db'], 'migrations');
});

$container['phpmig.migrations_path'] = __DIR__ . DIRECTORY_SEPARATOR . 'migrations';
$container['phpmig.command_prefix']  = 'phpmig';

$app->addCommands(
\Phpmig\Console\PhpmigApplication::getCommands($container)
);

All migrations down

Hi. I have implemented phpmig in my project long time ago.

Everything goes fine, but today, i've tried to migrate a new database migration to my server, in local it works pretty well, but in my RC server i've found ALL the migrations seems to be down in 'phpmig check':

$ bin/phpmig check
PHP Warning:  array_map(): Argument #2 should be an array in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Adapter/Illuminate/Database.php on line 62
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44
PHP Warning:  in_array() expects parameter 2 to be array, null given in /var/www/api/vendor/davedevelopment/phpmig/src/Phpmig/Console/Command/CheckCommand.php on line 44

 Status   Migration ID    Migration Name
-----------------------------------------
   down  20150101160236  CreateDBSeedsTable
   down  20151209133248  CreateRoleTable
   down  20151209160524  CreateUserTable
   down  20151209160530  CreateCompanyTable
   down  20151209160534  CreateTeamTable
   down  20151209175730  CreateTeamUserTable
   down  20151218102533  CreateTeamBeatTable
   down  20151218103048  CreateTeamBeatLabelTable
   down  20151222134913  CreateUserTeamBeatTable
   down  20151222152231  CreateTeamBeatValue
   down  20151222161002  CreateAnnotationTypeTable
   down  20151222161128  CreateAnnotationTable
   down  20151222171550  CreateUserInvitationTable
   down  20160111134935  CreateCommercialFormTable
   down  20160121160131  CreatePriceTable
   down  20160121160155  CreateCouponTable
   down  20160123120518  CreatePaymentTable
   down  20160218153809  AlterPriceTable
   down  20160218153831  AlterPaymentTable
   down  20160304100600  AlterUserTable
   down  20160308172803  AlterTeamTable
   down  20160309123010  CreateTeamBeatQuestionTable
   down  20160324225151  TeamGroup
   down  20160427203510  Goal
   down  20160501174940  StripeOnTeam
   down  20160502232915  NameOnPrice
   down  20160514142910  DynamicTips
   down  20160629123417  Statistics
   down  20160718173455  OnboardingStatus
   down  20160809100753  RoleId
   down  20160826115237  AnnotationDate
   down  20160915122009  CompanySector

But in fact, migrations are on my database except the last one (the new one).
What's happening here? Can you help me to understand?

Thanks!!

Generate default directory

I think phpmig generate command should default to the ./migrations directory. It makes its more user friendly.

Alternately the phpmig bootstrap file could point to the project preferred migration directory.

Re-ordering migrations

It would be nice to have the ability to re-order migrations.

Sometimes during dev you might find that what made sense, now doesn't make sense, however something you have already done depends on a changed new piece of code.

I know I could remove, delete, or just bodge the mysql table collecting info around migrations but be nice if there was an up and down cmd at the command line or something.

status command show 2147483647 at missing.

$ bin/phpmig --version
phpmig version dev

$ bin/phpmig status

 Status   Migration ID    Migration Name
-----------------------------------------
   up  20150427162348  CreatePickupProduct
   up      2147483647  ** MISSING **

Getting rid of dependency on pimple/pimple

Hi,

currently, phpmig has a hard dependency on pimple/pimple. Pimple is a nice piece of software because it is really lightweight. However, I don't like being dependent on multiple DICs. As there is no standardized interface for DICs so far, there are only two real solutions for this problem: either, having a hard dependency on a concrete DIC or working around this a little.

What I suggest is adding something like an abstract ´ContainerAdapter´ that is being initialized with the bootstrap file's return value. It is then used as a adapter to the actual container. I would add two concrete implementations to start: One adapter that uses the \ArrayAccess interface of the container and one that uses the container's get method.
Which adapter is used could be decided by first looking at the container's type (instanceof \ArrayAccess) and second testing for the existence of a get method. (This code could (and probably should) be encapsulated in a factory)

What do you think of this idea? If I find the time, I'll provide a PR later.

Cheers

Generate migration in local, apply them on a development server

I'm trying to generate migration on my machine which is rsynced with a development server, but phpmig keeps yelling at me because it can't connect to mysql.

Is there a way to just create the migration files and then migrate them just like I'm used to with laravel?

Using the wiki to help slim the readme down and make finding answers/instructions easier

The readme doc can be a bit intimidating to first time users. It'd be nice if we had the wiki page in use to clear some clutter out of the readme page, in order to find out a few things about this library, you have to scroll quite a bit to get past the different adapters (which having their own wiki page would be a great resource in my opinion) to learn how to use it in other ways.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.