Cloud Spanner: C# की मदद से गेमिंग लीडरबोर्ड बनाएं

1. खास जानकारी

Google Cloud Spanner, पूरी तरह से मैनेज की जाने वाली, हॉरिज़ॉन्टल तौर पर स्केल की जा सकने वाली, दुनिया भर में उपलब्ध, और रिलेशनल डेटाबेस सेवा है. यह बेहतर परफ़ॉर्मेंस और ज़्यादा अपटाइम के साथ-साथ, ACID ट्रांज़ैक्शन और SQL सिमैंटिक उपलब्ध कराती है.

इस लैब में, आपको Cloud Spanner इंस्टेंस को सेट अप करने का तरीका बताया जाएगा. आपको डेटाबेस और स्कीमा बनाने का तरीका बताया जाएगा. इनका इस्तेमाल गेमिंग लीडरबोर्ड के लिए किया जा सकता है. सबसे पहले, आपको खिलाड़ियों की जानकारी सेव करने के लिए, Players टेबल बनानी होगी. इसके बाद, खिलाड़ियों के स्कोर सेव करने के लिए, Scores टेबल बनानी होगी.

इसके बाद, टेबल में सैंपल डेटा डाला जाएगा. इसके बाद, लैब को पूरा करने के लिए, टॉप 10 सैंपल क्वेरी चलाएं. आखिर में, संसाधनों को खाली करने के लिए इंस्टेंस मिटाएं.

आपको क्या सीखने को मिलेगा

  • Cloud Spanner इंस्टेंस सेट अप करने का तरीका.
  • डेटाबेस और टेबल बनाने का तरीका.
  • कमिट टाइमस्टैंप कॉलम का इस्तेमाल करने का तरीका.
  • टाइमस्टैंप के साथ, Cloud Spanner डेटाबेस टेबल में डेटा लोड करने का तरीका.
  • Cloud Spanner डेटाबेस को क्वेरी करने का तरीका.
  • Cloud Spanner इंस्टेंस मिटाने का तरीका.

आपको इन चीज़ों की ज़रूरत होगी

  • कोई ब्राउज़र, जैसे कि Chrome या Firefox.

इस ट्यूटोरियल का इस्तेमाल कैसे किया जाएगा?

सिर्फ़ इसे पढ़ें इसे पढ़ें और एक्सरसाइज़ पूरी करें

Google Cloud Platform को इस्तेमाल करने के अपने अनुभव को आप क्या रेटिंग देंगे?

शुरुआती सामान्य एडवांस

2. सेटअप और ज़रूरी शर्तें

अपने हिसाब से एनवायरमेंट सेट अप करना

अगर आपके पास पहले से कोई Google खाता (Gmail या Google Apps) नहीं है, तो आपको एक खाता बनाना होगा. Google Cloud Platform Console ( console.cloud.google.com) में साइन इन करें और एक नया प्रोजेक्ट बनाएं.

अगर आपके पास पहले से कोई प्रोजेक्ट है, तो कंसोल में सबसे ऊपर बाईं ओर मौजूद, प्रोजेक्ट चुनने वाले पुल-डाउन मेन्यू पर क्लिक करें:

6c9406d9b014760.png

इसके बाद, नया प्रोजेक्ट बनाने के लिए, डायलॉग बॉक्स में मौजूद ‘नया प्रोजेक्ट' बटन पर क्लिक करें:

f708315ae07353d0.png

अगर आपके पास पहले से कोई प्रोजेक्ट नहीं है, तो आपको अपना पहला प्रोजेक्ट बनाने के लिए इस तरह का डायलॉग दिखेगा:

870a3cbd6541ee86.png

इसके बाद, प्रोजेक्ट बनाने के डायलॉग बॉक्स में, नए प्रोजेक्ट की जानकारी डाली जा सकती है:

6a92c57d3250a4b3.png

प्रोजेक्ट आईडी याद रखें. यह सभी Google Cloud प्रोजेक्ट के लिए एक यूनीक नाम होता है. ऊपर दिया गया नाम पहले ही इस्तेमाल किया जा चुका है. इसलिए, यह आपके लिए काम नहीं करेगा. माफ़ करें! इस कोड लैब में इसे बाद में PROJECT_ID के तौर पर दिखाया जाएगा.

इसके बाद, अगर आपने अब तक ऐसा नहीं किया है, तो आपको Google Cloud के संसाधनों का इस्तेमाल करने के लिए, Developers Console में बिलिंग चालू करनी होगी. साथ ही, Cloud Spanner API चालू करना होगा.

15d0ef27a8fbab27.png

इस कोडलैब को पूरा करने में आपको कुछ डॉलर से ज़्यादा खर्च नहीं करने पड़ेंगे. हालांकि, अगर आपको ज़्यादा संसाधनों का इस्तेमाल करना है या उन्हें चालू रखना है, तो यह खर्च बढ़ सकता है. इस दस्तावेज़ के आखिर में "सफाई" सेक्शन देखें. Google Cloud Spanner की कीमत के बारे में जानकारी यहां दी गई है.

Google Cloud Platform के नए उपयोगकर्ताओं को, मुफ़्त में आज़माने के लिए 300 डॉलर मिलते हैं. इससे इस कोडलैब का इस्तेमाल बिना किसी शुल्क के किया जा सकता है.

Google Cloud Shell सेटअप करना

Google Cloud और Spanner को लैपटॉप से रिमोटली ऐक्सेस किया जा सकता है. हालांकि, इस कोडलैब में हम Google Cloud Shell का इस्तेमाल करेंगे. यह क्लाउड में चलने वाला कमांड लाइन एनवायरमेंट है.

यह Debian पर आधारित वर्चुअल मशीन है. इसमें डेवलपमेंट के लिए ज़रूरी सभी टूल पहले से मौजूद हैं. यह 5 जीबी की होम डायरेक्ट्री उपलब्ध कराता है और Google Cloud में चलता है. इससे नेटवर्क की परफ़ॉर्मेंस और पुष्टि करने की प्रोसेस बेहतर होती है. इसका मतलब है कि इस कोडलैब के लिए, आपको सिर्फ़ एक ब्राउज़र की ज़रूरत होगी. हां, यह Chromebook पर भी काम करता है.

  1. Cloud Console से Cloud Shell चालू करने के लिए, बस Cloud Shell चालू करें gcLMt5IuEcJJNnMId-Bcz3sxCd0rZn7IzT_r95C8UZeqML68Y1efBG_B0VRp7hc7qiZTLAF-TXD7SsOadxn8uadgHhaLeASnVS3ZHK39eOlKJOgj9SJua_oeGhMxRrbOg3qigddS2A पर क्लिक करें. इसे चालू होने और एनवायरमेंट से कनेक्ट होने में कुछ ही समय लगेगा.

JjEuRXGg0AYYIY6QZ8d-66gx_Mtc-_jDE9ijmbXLJSAXFvJt-qUpNtsBsYjNpv2W6BQSrDc1D-ARINNQ-1EkwUhz-iUK-FUCZhJ-NtjvIEx9pIkE-246DomWuCfiGHK78DgoeWkHRw

Screen Shot 2017-06-14 at 10.13.43 PM.png

Cloud Shell से कनेक्ट होने के बाद, आपको दिखेगा कि आपकी पुष्टि पहले ही हो चुकी है और प्रोजेक्ट पहले से ही आपके PROJECT_ID पर सेट है.

gcloud auth list

कमांड आउटपुट

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

कमांड आउटपुट

[core]
project = <PROJECT_ID>

अगर किसी वजह से प्रोजेक्ट सेट नहीं है, तो यह कमांड दें:

gcloud config set project <PROJECT_ID>

क्या आपको PROJECT_ID की तलाश है? देखें कि आपने सेटअप के दौरान किस आईडी का इस्तेमाल किया था या Cloud Console के डैशबोर्ड में जाकर इसे देखें:

158fNPfwSxsFqz9YbtJVZes8viTS3d1bV4CVhij3XPxuzVFOtTObnwsphlm6lYGmgdMFwBJtc-FaLrZU7XHAg_ZYoCrgombMRR3h-eolLPcvO351c5iBv506B3ZwghZoiRg6cz23Qw

Cloud Shell, कुछ एनवायरमेंट वैरिएबल को डिफ़ॉल्ट रूप से भी सेट करता है. ये वैरिएबल, आने वाले समय में कमांड चलाने के दौरान आपके काम आ सकते हैं.

echo $GOOGLE_CLOUD_PROJECT

कमांड आउटपुट

<PROJECT_ID>
  1. आखिर में, डिफ़ॉल्ट ज़ोन और प्रोजेक्ट कॉन्फ़िगरेशन सेट करें.
gcloud config set compute/zone us-central1-f

आपके पास अलग-अलग ज़ोन चुनने का विकल्प होता है. ज़्यादा जानकारी के लिए, रीजन और ज़ोन देखें.

खास जानकारी

इस चरण में, आपको अपना एनवायरमेंट सेट अप करना होता है.

आगे बढ़ें

इसके बाद, आपको Cloud Spanner इंस्टेंस सेट अप करना होगा.

3. Cloud Spanner इंस्टेंस सेट अप करना

इस चरण में, हम इस कोडलैब के लिए अपना Cloud Spanner इंस्टेंस सेट अप करते हैं. सबसे ऊपर बाईं ओर मौजूद हैमबर्गर मेन्यू 1a6580bd3d3e6783.png में जाकर, Spanner एंट्री खोजें 3129589f7bc9e5ce.png या "/" दबाकर Spanner खोजें और "Spanner" टाइप करें

36e52f8df8e13b99.png

इसके बाद, 95269e75bc8c3e4d.png पर क्लिक करें और फ़ॉर्म भरें. इसके लिए, अपने इंस्टेंस के लिए इंस्टेंस का नाम cloudspanner-leaderboard डालें, कॉन्फ़िगरेशन चुनें (क्षेत्रीय इंस्टेंस चुनें), और नोड की संख्या सेट करें. इस कोडलैब के लिए, हमें सिर्फ़ एक नोड की ज़रूरत होगी. प्रोडक्शन इंस्टेंस के लिए और Cloud Spanner के एसएलए की ज़रूरी शर्तें पूरी करने के लिए, आपको अपने Cloud Spanner इंस्टेंस में तीन या उससे ज़्यादा नोड चलाने होंगे.

आखिर में, "बनाएं" पर क्लिक करें. इसके बाद, कुछ ही सेकंड में आपके पास Cloud Spanner इंस्टेंस उपलब्ध होगा.

dceb68e9ed3801e8.png

अगले चरण में, हम C# क्लाइंट लाइब्रेरी का इस्तेमाल करके, अपने नए इंस्टेंस में डेटाबेस और स्कीमा बनाएंगे.

4. डेटाबेस और स्कीमा बनाना

इस चरण में, हम अपना सैंपल डेटाबेस और स्कीमा बनाएंगे.

आइए, C# क्लाइंट लाइब्रेरी का इस्तेमाल करके दो टेबल बनाते हैं. पहली टेबल, खिलाड़ियों की जानकारी के लिए Players टेबल और दूसरी टेबल, खिलाड़ियों के स्कोर सेव करने के लिए Scores टेबल. इसके लिए, हम Cloud Shell में C# कंसोल ऐप्लिकेशन बनाने के चरणों के बारे में जानेंगे.

सबसे पहले, इस कोडलैब के लिए सैंपल कोड को Github से क्लोन करें. इसके लिए, Cloud Shell में यह निर्देश टाइप करें:

git clone https://github.com/GoogleCloudPlatform/dotnet-docs-samples.git

इसके बाद, डायरेक्ट्री को "applications" डायरेक्ट्री में बदलें. यहां आपको अपना ऐप्लिकेशन बनाना होगा.

cd dotnet-docs-samples/applications/

इस कोडलैब के लिए ज़रूरी सभी कोड, मौजूदा dotnet-docs-samples/applications/leaderboard डायरेक्ट्री में मौजूद है. इसे Leaderboard नाम के C# ऐप्लिकेशन के तौर पर चलाया जा सकता है. इससे आपको कोडलैब के दौरान रेफ़रंस के तौर पर मदद मिलेगी. हम एक नई डायरेक्ट्री बनाएंगे और लीडरबोर्ड ऐप्लिकेशन की कॉपी को चरणों में तैयार करेंगे.

ऐप्लिकेशन के लिए "codelab" नाम की नई डायरेक्ट्री बनाएं. इसके बाद, इस डायरेक्ट्री में जाने के लिए यह कमांड इस्तेमाल करें:

mkdir codelab && cd $_

नीचे दिए गए निर्देश का इस्तेमाल करके, "Leaderboard" नाम का नया .NET C# कंसोल ऐप्लिकेशन बनाएं:

dotnet new console -n Leaderboard

इस कमांड से एक सामान्य कंसोल ऐप्लिकेशन बनता है. इसमें दो मुख्य फ़ाइलें होती हैं: प्रोजेक्ट फ़ाइल Leaderboard.csproj और प्रोग्राम फ़ाइल Program.cs.

चलिए, इसे चलाते हैं. डायरेक्ट्री को नई लीडरबोर्ड डायरेक्ट्री में बदलें. यहां ऐप्लिकेशन मौजूद है:

cd Leaderboard

इसके बाद, इसे चलाने के लिए यह कमांड डालें.

dotnet run

आपको ऐप्लिकेशन का आउटपुट "Hello World!" दिखेगा.

अब हम अपने कंसोल ऐप्लिकेशन को अपडेट करेंगे. इसके लिए, Program.cs में बदलाव करके C# Spanner क्लाइंट लाइब्रेरी का इस्तेमाल करेंगे. इससे, हम दो टेबल Players और Scores वाली लीडरबोर्ड बना पाएंगे. Cloud Shell Editor में जाकर, यह काम किया जा सकता है:

नीचे हाइलाइट किए गए आइकॉन पर क्लिक करके, Cloud Shell Editor खोलें:

73cf70e05f653ca.png

इसके बाद, Cloud Shell Editor में Program.cs फ़ाइल खोलें. साथ ही, फ़ाइल के मौजूदा कोड को उस कोड से बदलें जिसकी ज़रूरत leaderboard डेटाबेस और Players और Scores टेबल बनाने के लिए होती है. इसके लिए, Program.cs फ़ाइल में यहां दिया गया C# ऐप्लिकेशन कोड चिपकाएं:

using System;
using System.Threading.Tasks;
using Google.Cloud.Spanner.Data;
using CommandLine;

namespace GoogleCloudSamples.Leaderboard
{
    [Verb("create", HelpText = "Create a sample Cloud Spanner database "
        + "along with sample 'Players' and 'Scores' tables in your project.")]
    class CreateOptions
    {
        [Value(0, HelpText = "The project ID of the project to use "
            + "when creating Cloud Spanner resources.", Required = true)]
        public string projectId { get; set; }
        [Value(1, HelpText = "The ID of the instance where the sample database "
            + "will be created.", Required = true)]
        public string instanceId { get; set; }
        [Value(2, HelpText = "The ID of the sample database to create.",
            Required = true)]
        public string databaseId { get; set; }
    }

    public class Program
    {
        enum ExitCode : int
        {
            Success = 0,
            InvalidParameter = 1,
        }

        public static object Create(string projectId,
            string instanceId, string databaseId)
        {
            var response =
                CreateAsync(projectId, instanceId, databaseId);
            Console.WriteLine("Waiting for operation to complete...");
            response.Wait();
            Console.WriteLine($"Operation status: {response.Status}");
            Console.WriteLine($"Created sample database {databaseId} on "
                + $"instance {instanceId}");
            return ExitCode.Success;
        }

        public static async Task CreateAsync(
            string projectId, string instanceId, string databaseId)
        {
            // Initialize request connection string for database creation.
            string connectionString =
                $"Data Source=projects/{projectId}/instances/{instanceId}";
            using (var connection = new SpannerConnection(connectionString))
            {
                string createStatement = $"CREATE DATABASE `{databaseId}`";
                string[] createTableStatements = new string[] {
                  // Define create table statement for Players table.
                  @"CREATE TABLE Players(
                    PlayerId INT64 NOT NULL,
                    PlayerName STRING(2048) NOT NULL
                  ) PRIMARY KEY(PlayerId)",
                  // Define create table statement for Scores table.
                  @"CREATE TABLE Scores(
                    PlayerId INT64 NOT NULL,
                    Score INT64 NOT NULL,
                    Timestamp TIMESTAMP NOT NULL OPTIONS(allow_commit_timestamp=true)
                  ) PRIMARY KEY(PlayerId, Timestamp),
                      INTERLEAVE IN PARENT Players ON DELETE NO ACTION" };
                // Make the request.
                var cmd = connection.CreateDdlCommand(
                    createStatement, createTableStatements);
                try
                {
                    await cmd.ExecuteNonQueryAsync();
                }
                catch (SpannerException e) when
                    (e.ErrorCode == ErrorCode.AlreadyExists)
                {
                    // OK.
                }
            }
        }

        public static int Main(string[] args)
        {
            var verbMap = new VerbMap<object>();
            verbMap
                .Add((CreateOptions opts) => Create(
                    opts.projectId, opts.instanceId, opts.databaseId))
                .NotParsedFunc = (err) => 1;
            return (int)verbMap.Run(args);
        }
    }
}

प्रोग्राम कोड के बारे में ज़्यादा जानकारी देने के लिए, यहां प्रोग्राम का एक डायग्राम दिया गया है. इसमें प्रोग्राम के मुख्य कॉम्पोनेंट को लेबल किया गया है:

b70b1b988ea3ac8a.png

dotnet-docs-samples/applications/leaderboard/step4 डायरेक्ट्री में मौजूद Program.cs फ़ाइल का इस्तेमाल करके, यह देखा जा सकता है कि create कमांड चालू करने के लिए कोड जोड़ने के बाद, आपकी Program.cs फ़ाइल कैसी दिखेगी.

इसके बाद, Cloud Shell Editor का इस्तेमाल करके प्रोग्राम की प्रोजेक्ट फ़ाइल Leaderboard.csproj खोलें और उसमें बदलाव करें. बदलाव करने के बाद, फ़ाइल में मौजूद कोड कुछ इस तरह दिखेगा. पक्का करें कि आपने Cloud Shell Editor के "फ़ाइल" मेन्यू का इस्तेमाल करके, अपने सभी बदलाव सेव कर लिए हों.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Google.Cloud.Spanner.Data" Version="3.3.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\..\..\commandlineutil\Lib\CommandLineUtil.csproj" />
  </ItemGroup>

</Project>

इस बदलाव में, C# Spanner Nuget पैकेज Google.Cloud.Spanner.Data का रेफ़रंस जोड़ा गया है. हमें Cloud Spanner API के साथ इंटरैक्ट करने के लिए इसकी ज़रूरत होती है. इस बदलाव में, CommandLineUtil प्रोजेक्ट का रेफ़रंस भी जोड़ा गया है. यह dotnet-doc-samples Github रिपॉज़िटरी का हिस्सा है. साथ ही, यह ओपन सोर्स CommandLineParser के लिए "verbmap" एक्सटेंशन उपलब्ध कराता है. यह कंसोल ऐप्लिकेशन के लिए कमांड लाइन इनपुट को मैनेज करने के लिए एक काम की लाइब्रेरी है.

dotnet-docs-samples/applications/leaderboard/step4 डायरेक्ट्री में मौजूद Leaderboard.csproj फ़ाइल का इस्तेमाल करके, यह देखा जा सकता है कि create कमांड चालू करने के लिए कोड जोड़ने के बाद, आपकी Leaderboard.csproj फ़ाइल कैसी दिखेगी.

अब अपडेट किए गए सैंपल को चलाया जा सकता है. अपने अपडेट किए गए ऐप्लिकेशन का डिफ़ॉल्ट जवाब देखने के लिए, यह टाइप करें:

dotnet run

आपको इस तरह का आउटपुट दिखेगा:

Leaderboard 1.0.0
Copyright (C) 2018 Leaderboard

ERROR(S):
  No verb selected.

  create     Create a sample Cloud Spanner database along with sample 'Players' and 'Scores' tables in your project.

  help       Display more information on a specific command.

  version    Display version information.

इस जवाब से पता चलता है कि यह Leaderboard ऐप्लिकेशन है. इसे तीन कमांड में से किसी एक के साथ चलाया जा सकता है: create, help, और version.

आइए, Spanner डेटाबेस और टेबल बनाने के लिए create कमांड का इस्तेमाल करें. कमांड के संभावित आर्ग्युमेंट देखने के लिए, बिना आर्ग्युमेंट के कमांड चलाएं.

dotnet run create

आपको कुछ इस तरह का जवाब दिखेगा:

Leaderboard 1.0.0
Copyright (C) 2018 Leaderboard

ERROR(S):
  A required value not bound to option name is missing.

  --help          Display this help screen.

  --version       Display version information.

  value pos. 0    Required. The project ID of the project to use when creating Cloud Spanner resources.

  value pos. 1    Required. The ID of the instance where the sample database will be created.

  value pos. 2    Required. The ID of the sample database to create.

यहां हम देख सकते हैं कि create कमांड के लिए, प्रोजेक्ट आईडी, इंस्टेंस आईडी, और डेटाबेस आईडी के तौर पर आर्ग्युमेंट की ज़रूरत होती है.

अब यह कमांड चलाएं. पक्का करें कि आपने PROJECT_ID की जगह, इस कोडलैब की शुरुआत में बनाया गया प्रोजेक्ट आईडी डाला हो.

dotnet run create PROJECT_ID cloudspanner-leaderboard leaderboard

कुछ सेकंड बाद, आपको इस तरह का जवाब दिखेगा:

Waiting for operation to complete...
Operation status: RanToCompletion
Created sample database leaderboard on instance cloudspanner-leaderboard

Cloud Console के Cloud Spanner सेक्शन में, आपको बाईं ओर मौजूद मेन्यू में अपना नया डेटाबेस और टेबल दिखनी चाहिए.

ba9008bb84cb90b0.png

अगले चरण में, हम अपने ऐप्लिकेशन को अपडेट करेंगे, ताकि आपके नए डेटाबेस में कुछ डेटा लोड किया जा सके.

5. डेटा लोड करें

अब हमारे पास leaderboard नाम का एक डेटाबेस है. इसमें दो टेबल हैं: Players और Scores. अब हम C# क्लाइंट लाइब्रेरी का इस्तेमाल करके, Players टेबल में प्लेयर और Scores टेबल में हर प्लेयर के लिए रैंडम स्कोर भरेंगे.

नीचे हाइलाइट किए गए आइकॉन पर क्लिक करके, Cloud Shell Editor खोलें:

4d17840699d8e7ce.png

इसके बाद, Cloud Shell Editor में Program.cs फ़ाइल में बदलाव करें, ताकि insert कमांड जोड़ी जा सके. इस कमांड का इस्तेमाल, Players टेबल में 100 खिलाड़ियों को जोड़ने के लिए किया जा सकता है. इसके अलावा, इसका इस्तेमाल Players टेबल में मौजूद हर खिलाड़ी के लिए, Scores टेबल में चार रैंडम स्कोर जोड़ने के लिए भी किया जा सकता है.

सबसे पहले, नीचे दिए गए प्रोग्राम में, मौजूदा create कमांड ब्लॉक के नीचे, सबसे ऊपर "Verbmap" में एक नया insert कमांड ब्लॉक जोड़ें:

[Verb("insert", HelpText = "Insert sample 'players' records or 'scores' records "
        + "into the database.")]
    class InsertOptions
    {
        [Value(0, HelpText = "The project ID of the project to use "
            + "when managing Cloud Spanner resources.", Required = true)]
        public string projectId { get; set; }
        [Value(1, HelpText = "The ID of the instance where the sample database resides.",
            Required = true)]
        public string instanceId { get; set; }
        [Value(2, HelpText = "The ID of the database where the sample database resides.",
            Required = true)]
        public string databaseId { get; set; }
        [Value(3, HelpText = "The type of insert to perform, 'players' or 'scores'.",
            Required = true)]
        public string insertType { get; set; }
    }

इसके बाद, मौजूदा CreateAsync तरीके के नीचे, Insert, InsertPlayersAsync, और InsertScoresAsync के ये तरीके जोड़ें:

        public static object Insert(string projectId,
            string instanceId, string databaseId, string insertType)
        {
            if (insertType.ToLower() == "players")
            {
                var responseTask =
                    InsertPlayersAsync(projectId, instanceId, databaseId);
                Console.WriteLine("Waiting for insert players operation to complete...");
                responseTask.Wait();
                Console.WriteLine($"Operation status: {responseTask.Status}");
            }
            else if (insertType.ToLower() == "scores")
            {
                var responseTask =
                    InsertScoresAsync(projectId, instanceId, databaseId);
                Console.WriteLine("Waiting for insert scores operation to complete...");
                responseTask.Wait();
                Console.WriteLine($"Operation status: {responseTask.Status}");
            }
            else
            {
                Console.WriteLine("Invalid value for 'type of insert'. "
                    + "Specify 'players' or 'scores'.");
                return ExitCode.InvalidParameter;
            }
            Console.WriteLine($"Inserted {insertType} into sample database "
                + $"{databaseId} on instance {instanceId}");
            return ExitCode.Success;
        }

       public static async Task InsertPlayersAsync(string projectId,
            string instanceId, string databaseId)
        {
            string connectionString =
                $"Data Source=projects/{projectId}/instances/{instanceId}"
                + $"/databases/{databaseId}";

            long numberOfPlayers = 0;
            using (var connection = new SpannerConnection(connectionString))
            {
                await connection.OpenAsync();
                await connection.RunWithRetriableTransactionAsync(async (transaction) =>
                {
                    // Execute a SQL statement to get current number of records
                    // in the Players table to use as an incrementing value 
                    // for each PlayerName to be inserted.
                    var cmd = connection.CreateSelectCommand(
                        @"SELECT Count(PlayerId) as PlayerCount FROM Players");
                    numberOfPlayers = await cmd.ExecuteScalarAsync<long>();
                    // Insert 100 player records into the Players table.
                    SpannerBatchCommand cmdBatch = connection.CreateBatchDmlCommand();
                    for (int i = 0; i < 100; i++)
                    {
                        numberOfPlayers++;
                        SpannerCommand cmdInsert = connection.CreateDmlCommand(
                            "INSERT INTO Players "
                            + "(PlayerId, PlayerName) "
                            + "VALUES (@PlayerId, @PlayerName)",
                                new SpannerParameterCollection {
                                    {"PlayerId", SpannerDbType.Int64},
                                    {"PlayerName", SpannerDbType.String}});
                        cmdInsert.Parameters["PlayerId"].Value =
                            Math.Abs(Guid.NewGuid().GetHashCode());
                        cmdInsert.Parameters["PlayerName"].Value =
                            $"Player {numberOfPlayers}";
                        cmdBatch.Add(cmdInsert);
                    }
                    await cmdBatch.ExecuteNonQueryAsync();
                });
            }
            Console.WriteLine("Done inserting player records...");
        }

        public static async Task InsertScoresAsync(
            string projectId, string instanceId, string databaseId)
        {
            string connectionString =
            $"Data Source=projects/{projectId}/instances/{instanceId}"
            + $"/databases/{databaseId}";

            // Insert 4 score records into the Scores table for each player
            // in the Players table.
            using (var connection = new SpannerConnection(connectionString))
            {
                await connection.OpenAsync();
                await connection.RunWithRetriableTransactionAsync(async (transaction) =>
                {
                    Random r = new Random();
                    bool playerRecordsFound = false;
                    SpannerBatchCommand cmdBatch =
                                connection.CreateBatchDmlCommand();
                    var cmdLookup =
                    connection.CreateSelectCommand("SELECT * FROM Players");
                    using (var reader = await cmdLookup.ExecuteReaderAsync())
                    {
                        while (await reader.ReadAsync())
                        {
                            playerRecordsFound = true;
                            for (int i = 0; i < 4; i++)
                            {
                                DateTime randomTimestamp = DateTime.Now
                                        .AddYears(r.Next(-2, 1))
                                        .AddMonths(r.Next(-12, 1))
                                        .AddDays(r.Next(-28, 0))
                                        .AddHours(r.Next(-24, 0))
                                        .AddSeconds(r.Next(-60, 0))
                                        .AddMilliseconds(r.Next(-100000, 0));
                                SpannerCommand cmdInsert =
                                connection.CreateDmlCommand(
                                    "INSERT INTO Scores "
                                    + "(PlayerId, Score, Timestamp) "
                                    + "VALUES (@PlayerId, @Score, @Timestamp)",
                                    new SpannerParameterCollection {
                                        {"PlayerId", SpannerDbType.Int64},
                                        {"Score", SpannerDbType.Int64},
                                        {"Timestamp",
                                            SpannerDbType.Timestamp}});
                                cmdInsert.Parameters["PlayerId"].Value =
                                    reader.GetFieldValue<int>("PlayerId");
                                cmdInsert.Parameters["Score"].Value =
                                    r.Next(1000, 1000001);
                                cmdInsert.Parameters["Timestamp"].Value =
                                    randomTimestamp.ToString("o");
                                cmdBatch.Add(cmdInsert);
                            }
                        }
                        if (!playerRecordsFound)
                        {
                            Console.WriteLine("Parameter 'scores' is invalid "
                            + "since no player records currently exist. First "
                            + "insert players then insert scores.");
                            Environment.Exit((int)ExitCode.InvalidParameter);
                        }
                        else
                        {
                            await cmdBatch.ExecuteNonQueryAsync();
                            Console.WriteLine(
                                "Done inserting score records..."
                            );
                        }
                    }
                });
            }
        }

इसके बाद, insert कमांड को काम करने लायक बनाने के लिए, अपने प्रोग्राम के "Main" तरीके में यह कोड जोड़ें:

                .Add((InsertOptions opts) => Insert(
                    opts.projectId, opts.instanceId, opts.databaseId, opts.insertType))

dotnet-docs-samples/applications/leaderboard/step5 डायरेक्ट्री में मौजूद Program.cs फ़ाइल का इस्तेमाल करके, यह देखा जा सकता है कि insert कमांड चालू करने के लिए कोड जोड़ने के बाद, आपकी Program.cs फ़ाइल कैसी दिखेगी.

अब प्रोग्राम को चलाकर यह पुष्टि करते हैं कि नई insert कमांड, प्रोग्राम की संभावित कमांड की सूची में शामिल है. यह कमांड चलाएं:

dotnet run

अब आपको प्रोग्राम के डिफ़ॉल्ट आउटपुट में insert कमांड दिखेगी:

Leaderboard 1.0.0
Copyright (C) 2018 Leaderboard

ERROR(S):
  No verb selected.

  create     Create a sample Cloud Spanner database along with sample 'Players' and 'Scores' tables in your project.

  insert     Insert sample 'players' records or 'scores' records into the database.

  help       Display more information on a specific command.

  version    Display version information.

अब insert कमांड चलाकर देखते हैं कि इसके इनपुट आर्ग्युमेंट क्या हैं. यह कमांड डालें.

dotnet run insert

इससे यह जवाब मिलना चाहिए:

Leaderboard 1.0.0
Copyright (C) 2018 Leaderboard

ERROR(S):
  A required value not bound to option name is missing.

  --help          Display this help screen.

  --version       Display version information.

  value pos. 0    Required. The project ID of the project to use when managing Cloud Spanner resources.

  value pos. 1    Required. The ID of the instance where the sample database resides.

  value pos. 2    Required. The ID of the database where the sample database resides.

  value pos. 3    Required. The type of insert to perform, 'players' or 'scores'.

जवाब से पता चलता है कि प्रोजेक्ट आईडी, इंस्टेंस आईडी, और डेटाबेस आईडी के अलावा, एक और तर्क value pos. 3 ज़रूरी है. यह "टाइप ऑफ़ इंसर्ट" है. इस तर्क की वैल्यू ‘players' या ‘scores' हो सकती है.

अब हम insert कमांड को उसी आर्ग्युमेंट वैल्यू के साथ चलाएंगे जिसका इस्तेमाल हमने create कमांड को कॉल करते समय किया था. साथ ही, "players" को "टाइप ऑफ़ इंसर्ट" आर्ग्युमेंट के तौर पर जोड़ेंगे. पक्का करें कि आपने PROJECT_ID की जगह, इस कोडलैब की शुरुआत में बनाया गया प्रोजेक्ट आईडी डाला हो.

dotnet run insert PROJECT_ID cloudspanner-leaderboard leaderboard players

कुछ सेकंड बाद, आपको इस तरह का जवाब दिखेगा:

Waiting for insert players operation to complete...
Done inserting player records...
Operation status: RanToCompletion
Inserted players into sample database leaderboard on instance cloudspanner-leaderboard

अब, C# क्लाइंट लाइब्रेरी का इस्तेमाल करके, Scores टेबल में चार रैंडम स्कोर भरते हैं. साथ ही, Players टेबल में मौजूद हर खिलाड़ी के लिए टाइमस्टैंप भी भरते हैं.

Scores टेबल के Timestamp कॉलम को "कमिट टाइमस्टैंप" कॉलम के तौर पर तय किया गया था. इसके लिए, हमने यह SQL स्टेटमेंट इस्तेमाल किया था. यह स्टेटमेंट तब लागू हुआ था, जब हमने पहले create कमांड को चलाया था:

CREATE TABLE Scores(
  PlayerId INT64 NOT NULL,
  Score INT64 NOT NULL,
  Timestamp TIMESTAMP NOT NULL OPTIONS(allow_commit_timestamp=true)
) PRIMARY KEY(PlayerId, Timestamp),
    INTERLEAVE IN PARENT Players ON DELETE NO ACTION

OPTIONS(allow_commit_timestamp=true) एट्रिब्यूट पर ध्यान दें. इससे Timestamp "कमिट टाइमस्टैंप" कॉलम बन जाता है. साथ ही, यह किसी टेबल की लाइन में INSERT और UPDATE कार्रवाइयों के लिए, सटीक लेन-देन के टाइमस्टैंप के साथ अपने-आप भर जाता है.

"कमिट टाइमस्टैंप" कॉलम में, अपने टाइमस्टैंप की वैल्यू भी डाली जा सकती हैं. हालांकि, इसके लिए आपको ऐसा टाइमस्टैंप डालना होगा जिसकी वैल्यू आज से पहले की तारीख हो. इस कोडलैब के लिए, हम ऐसा ही करेंगे.

अब हम insert कमांड को उसी आर्ग्युमेंट वैल्यू के साथ चलाएंगे जिसका इस्तेमाल हमने create कमांड को कॉल करते समय किया था. साथ ही, "स्कोर" को "टाइप ऑफ़ इंसर्ट" आर्ग्युमेंट के तौर पर जोड़ेंगे. पक्का करें कि आपने PROJECT_ID की जगह, इस कोडलैब की शुरुआत में बनाया गया प्रोजेक्ट आईडी डाला हो.

dotnet run insert PROJECT_ID cloudspanner-leaderboard leaderboard scores

कुछ सेकंड बाद, आपको इस तरह का जवाब दिखेगा:

Waiting for insert players operation to complete...
Done inserting player records...
Operation status: RanToCompletion
Inserted players into sample database leaderboard on instance cloudspanner-leaderboard

insert को scores के तौर पर तय किए गए "टाइप ऑफ़ इंसर्ट" के साथ चलाने पर, InsertScoresAsync तरीके को कॉल किया जाता है. यह तरीका, नीचे दिए गए कोड स्निपेट का इस्तेमाल करके, तारीख और समय के साथ रैंडम तरीके से जनरेट किया गया टाइमस्टैंप डालता है:

DateTime randomTimestamp = DateTime.Now
    .AddYears(r.Next(-2, 1))
    .AddMonths(r.Next(-12, 1))
    .AddDays(r.Next(-28, 0))
    .AddHours(r.Next(-24, 0))
    .AddSeconds(r.Next(-60, 0))
    .AddMilliseconds(r.Next(-100000, 0));
...
 cmdInsert.Parameters["Timestamp"].Value = randomTimestamp.ToString("o");

"Insert" लेन-देन कब हुआ, इसकी टाइमस्टैंप की जानकारी Timestamp कॉलम में अपने-आप भरने के लिए, C# कॉन्स्टेंट SpannerParameter.CommitTimestamp डालें. इसे नीचे दिए गए कोड स्निपेट में दिखाया गया है:

cmd.Parameters["Timestamp"].Value = SpannerParameter.CommitTimestamp;

डेटा लोड हो गया है. अब हम उन वैल्यू की पुष्टि करते हैं जिन्हें हमने अभी-अभी नई टेबल में लिखा है. पहले leaderboard डेटाबेस चुनें. इसके बाद, Players टेबल चुनें. Data टैब पर क्लिक करें. आपको दिखेगा कि टेबल के PlayerId और PlayerName कॉलम में डेटा मौजूद है.

7bc2c96293c31c49.png

इसके बाद, आइए पुष्टि करें कि स्कोर टेबल में भी डेटा है. इसके लिए, Scores टेबल पर क्लिक करें और Data टैब चुनें. आपको टेबल के PlayerId, Timestamp, और Score कॉलम में डेटा दिखेगा.

d8a4ee4f13244c19.png

बहुत खूब! आइए, अपने प्रोग्राम को अपडेट करें, ताकि हम कुछ ऐसी क्वेरी चला सकें जिनका इस्तेमाल गेमिंग लीडरबोर्ड बनाने के लिए किया जा सकता है.

6. लीडरबोर्ड की क्वेरी चलाना

हमने अपना डेटाबेस सेट अप कर लिया है और अपनी टेबल में जानकारी लोड कर ली है. अब इस डेटा का इस्तेमाल करके, लीडरबोर्ड बनाते हैं. इसके लिए, हमें इन चार सवालों के जवाब देने होंगे:

  1. अब तक के "टॉप टेन" खिलाड़ी कौनसे हैं?
  2. इस साल के "टॉप टेन" खिलाड़ी कौनसे हैं?
  3. महीने के "टॉप टेन" खिलाड़ी कौनसे हैं?
  4. इस हफ़्ते के "टॉप टेन" खिलाड़ी कौनसे हैं?

आइए, हम अपने प्रोग्राम को अपडेट करते हैं, ताकि एसक्यूएल क्वेरी चलाई जा सकें और इन सवालों के जवाब मिल सकें.

हम query कमांड जोड़ेंगे. इससे क्वेरी चलाने का एक तरीका मिलेगा. इससे उन सवालों के जवाब मिलेंगे जिनसे लीडरबोर्ड के लिए ज़रूरी जानकारी मिलेगी.

प्रोग्राम को अपडेट करने के लिए, Cloud Shell Editor में Program.cs फ़ाइल में बदलाव करें, ताकि query कमांड जोड़ी जा सके.

सबसे पहले, नीचे दिए गए प्रोग्राम में, मौजूदा insert कमांड ब्लॉक के नीचे, सबसे ऊपर "Verbmap" में एक नया query कमांड ब्लॉक जोड़ें:

    [Verb("query", HelpText = "Query players with 'Top Ten' scores within a specific timespan "
        + "from sample Cloud Spanner database table.")]
    class QueryOptions
    {
        [Value(0, HelpText = "The project ID of the project to use "
            + "when managing Cloud Spanner resources.", Required = true)]
        public string projectId { get; set; }
        [Value(1, HelpText = "The ID of the instance where the sample data resides.",
            Required = true)]
        public string instanceId { get; set; }
        [Value(2, HelpText = "The ID of the database where the sample data resides.",
            Required = true)]
        public string databaseId { get; set; }
        [Value(3, Default = 0, HelpText = "The timespan in hours that will be used to filter the "
            + "results based on a record's timestamp. The default will return the "
            + "'Top Ten' scores of all time.")]
        public int timespan { get; set; }
    }

इसके बाद, मौजूदा InsertScoresAsync तरीके के नीचे, यहां दिए गए Query और QueryAsync तरीके जोड़ें:

public static object Query(string projectId,
            string instanceId, string databaseId, int timespan)
        {
            var response = QueryAsync(
                projectId, instanceId, databaseId, timespan);
            response.Wait();
            return ExitCode.Success;
        }        

public static async Task QueryAsync(
            string projectId, string instanceId, string databaseId, int timespan)
        {
            string connectionString =
            $"Data Source=projects/{projectId}/instances/"
            + $"{instanceId}/databases/{databaseId}";
            // Create connection to Cloud Spanner.
            using (var connection = new SpannerConnection(connectionString))
            {
                string sqlCommand;
                if (timespan == 0)
                {
                    // No timespan specified. Query Top Ten scores of all time.
                    sqlCommand =
                        @"SELECT p.PlayerId, p.PlayerName, s.Score, s.Timestamp
                            FROM Players p
                            JOIN Scores s ON p.PlayerId = s.PlayerId
                            ORDER BY s.Score DESC LIMIT 10";
                }
                else
                {
                    // Query Top Ten scores filtered by the timepan specified.
                    sqlCommand =
                        $@"SELECT p.PlayerId, p.PlayerName, s.Score, s.Timestamp
                            FROM Players p
                            JOIN Scores s ON p.PlayerId = s.PlayerId
                            WHERE s.Timestamp >
                            TIMESTAMP_SUB(CURRENT_TIMESTAMP(),
                                INTERVAL {timespan.ToString()} HOUR)
                            ORDER BY s.Score DESC LIMIT 10";
                }
                var cmd = connection.CreateSelectCommand(sqlCommand);
                using (var reader = await cmd.ExecuteReaderAsync())
                {
                    while (await reader.ReadAsync())
                    {
                        Console.WriteLine("PlayerId : "
                          + reader.GetFieldValue<string>("PlayerId")
                          + " PlayerName : "
                          + reader.GetFieldValue<string>("PlayerName")
                          + " Score : "
                          + string.Format("{0:n0}",
                            Int64.Parse(reader.GetFieldValue<string>("Score")))
                          + " Timestamp : "
                          + reader.GetFieldValue<string>("Timestamp").Substring(0, 10));
                    }
                }
            }
        }

इसके बाद, query कमांड को काम करने लायक बनाने के लिए, अपने प्रोग्राम के "Main" तरीके में यह कोड जोड़ें:

                .Add((QueryOptions opts) => Query(
                    opts.projectId, opts.instanceId, opts.databaseId, opts.timespan))

dotnet-docs-samples/applications/leaderboard/step6 डायरेक्ट्री में मौजूद Program.cs फ़ाइल का इस्तेमाल करके, यह देखा जा सकता है कि query कमांड चालू करने के लिए कोड जोड़ने के बाद, आपकी Program.cs फ़ाइल कैसी दिखेगी.

अब प्रोग्राम को चलाकर यह पुष्टि करते हैं कि नई query कमांड, प्रोग्राम की संभावित कमांड की सूची में शामिल है. यह कमांड चलाएं:

dotnet run

अब आपको प्रोग्राम के डिफ़ॉल्ट आउटपुट में, query कमांड को नए कमांड विकल्प के तौर पर शामिल किया गया दिखेगा:

Leaderboard 1.0.0
Copyright (C) 2018 Leaderboard

ERROR(S):
  No verb selected.

  create     Create a sample Cloud Spanner database along with sample 'Players' and 'Scores' tables in your project.

  insert     Insert sample 'players' records or 'scores' records into the database.

  query      Query players with 'Top Ten' scores within a specific timespan from sample Cloud Spanner database table.

  help       Display more information on a specific command.

  version    Display version information.

अब query कमांड चलाकर देखते हैं कि इसके इनपुट आर्ग्युमेंट क्या हैं. नीचे दिए गए कमांड डालें:

dotnet run query

इससे यह जवाब मिलेगा:

Leaderboard 1.0.0
Copyright (C) 2018 Leaderboard

ERROR(S):
  A required value not bound to option name is missing.

  --help          Display this help screen.

  --version       Display version information.

  value pos. 0    Required. The project ID of the project to use when managing Cloud Spanner resources.

  value pos. 1    Required. The ID of the instance where the sample data resides.

  value pos. 2    Required. The ID of the database where the sample data resides.

  value pos. 3    (Default: 0) The timespan in hours that will be used to filter the results based on a record's timestamp. The default will return the 'Top Ten' scores of all time.

जवाब से पता चलता है कि प्रोजेक्ट आईडी, इंस्टेंस आईडी, और डेटाबेस आईडी के अलावा, एक और आर्ग्युमेंट value pos. 3 की ज़रूरत है. इससे हमें घंटों की संख्या में समयसीमा तय करने की अनुमति मिलती है. इसका इस्तेमाल, Scores टेबल के Timestamp कॉलम में मौजूद वैल्यू के आधार पर रिकॉर्ड फ़िल्टर करने के लिए किया जाता है. इस आर्ग्युमेंट की डिफ़ॉल्ट वैल्यू 0 होती है. इसका मतलब है कि टाइमस्टैंप के हिसाब से कोई भी रिकॉर्ड फ़िल्टर नहीं किया जाएगा. इसलिए, हम query कमांड का इस्तेमाल "टाइम्सपैन" वैल्यू के बिना कर सकते हैं, ताकि हमें अब तक के "टॉप टेन" खिलाड़ियों की सूची मिल सके.

आइए, "timespan" तय किए बिना query कमांड चलाएं. इसके लिए, हम वही तर्क वैल्यू इस्तेमाल करेंगे जो हमने create कमांड चलाते समय इस्तेमाल की थीं. पक्का करें कि आपने PROJECT_ID की जगह, इस कोडलैब की शुरुआत में बनाया गया प्रोजेक्ट आईडी डाला हो.

dotnet run query PROJECT_ID cloudspanner-leaderboard leaderboard

आपको ऐसा जवाब दिखेगा जिसमें अब तक के "टॉप टेन" खिलाड़ियों के नाम शामिल होंगे. जैसे:

PlayerId : 1843159180 PlayerName : Player 87 Score : 998,955 Timestamp : 2016-03-23
PlayerId : 61891198 PlayerName : Player 19 Score : 998,720 Timestamp : 2016-03-26
PlayerId : 340906298 PlayerName : Player 48 Score : 993,302 Timestamp : 2015-08-27
PlayerId : 541473117 PlayerName : Player 22 Score : 991,368 Timestamp : 2018-04-30
PlayerId : 857460496 PlayerName : Player 68 Score : 988,010 Timestamp : 2015-05-25
PlayerId : 1826646419 PlayerName : Player 91 Score : 984,022 Timestamp : 2016-11-26
PlayerId : 1002199735 PlayerName : Player 35 Score : 982,933 Timestamp : 2015-09-26
PlayerId : 2002563755 PlayerName : Player 23 Score : 979,041 Timestamp : 2016-10-25
PlayerId : 1377548191 PlayerName : Player 2 Score : 978,632 Timestamp : 2016-05-02
PlayerId : 1358098565 PlayerName : Player 65 Score : 973,257 Timestamp : 2016-10-30

अब ज़रूरी आर्ग्युमेंट के साथ query कमांड चलाएं. इससे साल के "टॉप टेन" खिलाड़ियों के बारे में क्वेरी की जा सकेगी. इसके लिए, "टाइम्सपैन" को एक साल में घंटों की संख्या के बराबर सेट करें. यह संख्या 8,760 है. पक्का करें कि आपने PROJECT_ID की जगह, इस कोडलैब की शुरुआत में बनाया गया प्रोजेक्ट आईडी डाला हो.

dotnet run query PROJECT_ID cloudspanner-leaderboard leaderboard 8760

आपको ऐसा जवाब दिखेगा जिसमें साल के "टॉप टेन" खिलाड़ियों के नाम शामिल होंगे. जैसे:

PlayerId : 541473117 PlayerName : Player 22 Score : 991,368 Timestamp : 2018-04-30
PlayerId : 228469898 PlayerName : Player 82 Score : 967,177 Timestamp : 2018-01-26
PlayerId : 1131343000 PlayerName : Player 26 Score : 944,725 Timestamp : 2017-05-26
PlayerId : 396780730 PlayerName : Player 41 Score : 929,455 Timestamp : 2017-09-26
PlayerId : 61891198 PlayerName : Player 19 Score : 921,251 Timestamp : 2018-05-01
PlayerId : 634269851 PlayerName : Player 54 Score : 909,379 Timestamp : 2017-07-24
PlayerId : 821111159 PlayerName : Player 55 Score : 908,402 Timestamp : 2017-05-25
PlayerId : 228469898 PlayerName : Player 82 Score : 889,040 Timestamp : 2017-12-26
PlayerId : 1408782275 PlayerName : Player 27 Score : 874,124 Timestamp : 2017-09-24
PlayerId : 1002199735 PlayerName : Player 35 Score : 864,758 Timestamp : 2018-04-24

अब महीने के "टॉप टेन" खिलाड़ियों के बारे में क्वेरी करने के लिए, query कमांड चलाएं. इसके लिए, "timespan" को एक महीने में मौजूद घंटों की संख्या के बराबर सेट करें. यह संख्या 730 है. पक्का करें कि आपने PROJECT_ID की जगह, इस कोडलैब की शुरुआत में बनाया गया प्रोजेक्ट आईडी डाला हो.

dotnet run query PROJECT_ID cloudspanner-leaderboard leaderboard 730

आपको ऐसा जवाब दिखेगा जिसमें महीने के "टॉप टेन" खिलाड़ियों के नाम शामिल होंगे. जैसे:

PlayerId : 541473117 PlayerName : Player 22 Score : 991,368 Timestamp : 2018-04-30
PlayerId : 61891198 PlayerName : Player 19 Score : 921,251 Timestamp : 2018-05-01
PlayerId : 1002199735 PlayerName : Player 35 Score : 864,758 Timestamp : 2018-04-24
PlayerId : 1228490432 PlayerName : Player 11 Score : 682,033 Timestamp : 2018-04-26
PlayerId : 648239230 PlayerName : Player 92 Score : 653,895 Timestamp : 2018-05-02
PlayerId : 70762849 PlayerName : Player 77 Score : 598,074 Timestamp : 2018-04-22
PlayerId : 1671215342 PlayerName : Player 62 Score : 506,770 Timestamp : 2018-04-28
PlayerId : 1208850523 PlayerName : Player 21 Score : 216,008 Timestamp : 2018-04-30
PlayerId : 1587692674 PlayerName : Player 63 Score : 188,157 Timestamp : 2018-04-25
PlayerId : 992391797 PlayerName : Player 37 Score : 167,175 Timestamp : 2018-04-30

अब "टॉप टेन" खिलाड़ियों के बारे में क्वेरी करने के लिए, query कमांड चलाएं. इसके लिए, "टाइम्सपैन" को एक हफ़्ते में मौजूद घंटों की संख्या के बराबर सेट करें. यह संख्या 168 है. पक्का करें कि आपने PROJECT_ID की जगह, इस कोडलैब की शुरुआत में बनाया गया प्रोजेक्ट आईडी डाला हो.

dotnet run query PROJECT_ID cloudspanner-leaderboard leaderboard 168

आपको ऐसा जवाब दिखेगा जिसमें हफ़्ते के "टॉप टेन" खिलाड़ियों के नाम शामिल होंगे. जैसे:

PlayerId : 541473117 PlayerName : Player 22 Score : 991,368 Timestamp : 2018-04-30
PlayerId : 61891198 PlayerName : Player 19 Score : 921,251 Timestamp : 2018-05-01
PlayerId : 228469898 PlayerName : Player 82 Score : 853,602 Timestamp : 2018-04-28
PlayerId : 1131343000 PlayerName : Player 26 Score : 695,318 Timestamp : 2018-04-30
PlayerId : 1228490432 PlayerName : Player 11 Score : 682,033 Timestamp : 2018-04-26
PlayerId : 1408782275 PlayerName : Player 27 Score : 671,827 Timestamp : 2018-04-27
PlayerId : 648239230 PlayerName : Player 92 Score : 653,895 Timestamp : 2018-05-02
PlayerId : 816861444 PlayerName : Player 83 Score : 622,277 Timestamp : 2018-04-27
PlayerId : 162043954 PlayerName : Player 75 Score : 572,634 Timestamp : 2018-05-02
PlayerId : 1671215342 PlayerName : Player 62 Score : 506,770 Timestamp : 2018-04-28

बहुत बढ़िया!

अब जैसे-जैसे रिकॉर्ड जोड़े जाएंगे, Spanner आपके डेटाबेस को आपकी ज़रूरत के हिसाब से स्केल करता जाएगा.

आपका डेटाबेस कितना भी बड़ा हो जाए, Spanner और इसकी Truetime टेक्नोलॉजी की मदद से, आपके गेम की लीडरबोर्ड को सटीक तरीके से स्केल किया जा सकता है.

7. साफ़-सफ़ाई सेवा

Spanner का इस्तेमाल करने के बाद, हमें अपने प्लेग्राउंड को साफ़ करना होगा. इससे हम कीमती संसाधनों और पैसे को बचा पाएंगे. अच्छी बात यह है कि यह एक आसान चरण है. बस डेवलपर कंसोल में जाएं और कोडलैब के उस चरण में बनाए गए इंस्टेंस को मिटाएं जिसका नाम "Cloud Spanner इंस्टेंस सेट अप करें" है.

8. बधाई हो!

हमने इन विषयों पर बात की:

  • लीडरबोर्ड के लिए Google Cloud Spanner इंस्टेंस, डेटाबेस, और टेबल स्कीमा
  • .NET Core C# कंसोल ऐप्लिकेशन बनाने का तरीका
  • C# क्लाइंट लाइब्रेरी का इस्तेमाल करके, Spanner डेटाबेस और टेबल बनाने का तरीका
  • C# क्लाइंट लाइब्रेरी का इस्तेमाल करके, Spanner डेटाबेस में डेटा लोड करने का तरीका
  • Spanner कमिट टाइमस्टैंप और C# क्लाइंट लाइब्रेरी का इस्तेमाल करके, अपने डेटा से "टॉप टेन" नतीजे पाने के लिए क्वेरी करने का तरीका

अगले चरण:

हमें सुझाव/राय दें या शिकायत करें

  • कृपया थोड़ा समय निकालकर, हमारे छोटे से सर्वे में हिस्सा लें