Uploaded image for project: 'CUBRID APIs'
  1. CUBRID APIs
  2. APIS-728

[ADO.NET]The DbConnection.GetSchema(string) should return null if the collectionName is invalid

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: ADO.NET 9.3.0.0001
    • Fix Version/s: ADO.NET 9.3.0.0001
    • Component/s: ADO.NET
    • Labels:
    • Environment:

      Test Build: 9.3.0.0145
      Test OS: Windows 32bit
      .NET: 4.0
      Driver: cubrid-ado.net 9.3.0.0001(20140224)

      Description

      Currently, if the argument collectionName is specified as an invalid/non-existent value in GetSchema(string), it returns an ArgumentNullException.

      However, GetSchema(string) could only return an ArgumentException if the collectionName is specified as null (i.e. GetSchema(null)) http://msdn.microsoft.com/en-us/library/22936zd1(v=vs.100).aspx

      Thus, if the argument collectionName is specified as an invalid/non-existent value in GetSchema(string), it should returns a null value rather than an ArgumentNullException

      Scenario

      {code}
      CUBRIDConnection conn = new CUBRIDConnection()
      conn.ConnectionString = "server=localhost;database=demodb;port=33000;user=public;password=";
      conn.Open();

      dt = conn.GetSchema("TABLES");{code}

      Actual Result:

      System.ArgumentNullException: Value cannot be null.
      Parameter name: No filters were specified!
      

      Expect Result: No exception thrown, dt should be a null value

      1. APIS-728.creview
        39 kB
        唐勤
      2. APIS-728.creview
        39 kB
        唐勤
      3. APIS-728.creview
        39 kB
        唐勤

        Activity

        Hide
        cn16359 唐勤 added a comment -

        ArgumentNullException is not caused by invalid/non-existent collectionName. It is caused by another internal bug.
        The call stack of conn.GetSchema("TABLES") is:

        conn.GetSchema("TABLES")
          -->conn.GetSchema("TABLES", null)
            -->SchemaProvider.GetSchema("TABLES", null)
              -->SchemaProvider.GetTables(null)
        

        But in the implementation of SchemaProvider.GetTables, ArgumentNullException will be thrown if filters == null as below code:

        {code}
        if (filters == null)
        throw new ArgumentNullException(Utils.GetStr(MsgId.NoFiltersSpecified));{code}

        I'm fixing it.

        Show
        cn16359 唐勤 added a comment - ArgumentNullException is not caused by invalid/non-existent collectionName. It is caused by another internal bug. The call stack of conn.GetSchema("TABLES") is: conn.GetSchema("TABLES") -->conn.GetSchema("TABLES", null) -->SchemaProvider.GetSchema("TABLES", null) -->SchemaProvider.GetTables(null) But in the implementation of SchemaProvider.GetTables , ArgumentNullException will be thrown if filters == null as below code: {code} if (filters == null) throw new ArgumentNullException(Utils.GetStr(MsgId.NoFiltersSpecified));{code} I'm fixing it.
        Hide
        cn16359 唐勤 added a comment - - edited

        "filters" specifies a set of restriction values for the requested schema. It can supply n depth of values. If the requested schema is "tables", "filters" should be

        {"table name pattern"}

        .
        1. Modify the implementation of CUBRIDSchemaProvider.GetTables(string[] filters) as below:
        a. If the table name pattern is null, the default filters "%" is used.
        b. If the length of filters > 1, the first table name is used.

        {code}
        if (filters == null || filters.Length == 0)
        {
        filters = new string[1] { "%" };
        }
        else if (filters.Length > 1)
        {
        filters = new string[1] { filters[0] };
        }{code}

        2. Modify the implementation of CUBRIDSchemaProvider.FindTables(DataTable schemaTable, string[] filters).

        {code}
        string table_name_pattern = filters[0];
        if (table_name_pattern == null)
        { table_name_pattern = "%"; }{code}

        3. Add comments.

        Show
        cn16359 唐勤 added a comment - - edited "filters" specifies a set of restriction values for the requested schema. It can supply n depth of values. If the requested schema is "tables", "filters" should be {"table name pattern"} . 1. Modify the implementation of CUBRIDSchemaProvider.GetTables(string[] filters) as below: a. If the table name pattern is null, the default filters "%" is used. b. If the length of filters > 1, the first table name is used. {code} if (filters == null || filters.Length == 0) { filters = new string [1] { "%" }; } else if (filters.Length > 1) { filters = new string [1] { filters[0] }; }{code} 2. Modify the implementation of CUBRIDSchemaProvider.FindTables(DataTable schemaTable, string[] filters). {code} string table_name_pattern = filters [0] ; if (table_name_pattern == null) { table_name_pattern = "%"; }{code} 3. Add comments.
        Hide
        cn16359 唐勤 added a comment - - edited

        Same problems exist when get the schema of other collectionNames:
        1. USERS
        2. DATABASES
        3. PROCEDURES
        4. VIEWS
        5. COLUMNS
        6. INDEXES
        7. INDEX_COLUMNS
        8. FOREIGN_KEYS
        Also change the implementation of getting the schema of these collectionNames.
        Besides, add comments to CUBRIDConnection.GetSchema() to explain how to get schema of different collectionName.

        Show
        cn16359 唐勤 added a comment - - edited Same problems exist when get the schema of other collectionNames: 1. USERS 2. DATABASES 3. PROCEDURES 4. VIEWS 5. COLUMNS 6. INDEXES 7. INDEX_COLUMNS 8. FOREIGN_KEYS Also change the implementation of getting the schema of these collectionNames. Besides, add comments to CUBRIDConnection.GetSchema() to explain how to get schema of different collectionName.
        Hide
        cn16359 唐勤 added a comment -

        Fixed.

        Show
        cn16359 唐勤 added a comment - Fixed.
        Hide
        cn16359 唐勤 added a comment -

        Let GetColumns, GetIndexes GetIndexColumns, and GetForeignKeys in CUBRIDSchemaProvider.cs use "comparing filters with a null" only once.

        Show
        cn16359 唐勤 added a comment - Let GetColumns, GetIndexes GetIndexColumns, and GetForeignKeys in CUBRIDSchemaProvider.cs use "comparing filters with a null" only once.
        Hide
        cn16359 唐勤 added a comment -

        Improve the implementation of CUBRIDConnection.GetSchema()
        Change it to return the meta data of supported collection names.
        1. In CUBRIDConnection.cs

        {code}
        public override DataTable GetSchema()
        { return GetSchema(CUBRIDSchemaProvider.MetaCollectionName); }{code}

        2. In CUBRIDSchemaProvider.cs

        {code}
        private static DataTable GetMetaDataCollections()
        {
        object[][] collections = new object[][]
        {
        new object[] {CUBRIDSchemaProvider.MetaCollectionName, 0},
        new Object[] {"ReservedWords", 0},
        new Object[] {"Users",1},
        new Object[] {"Databases", 1},
        new Object[] {"Procedures", 1},
        new Object[] {"Tables", 1},
        new Object[] {"Views", 1},
        new Object[] {"Columns", 2},
        new Object[] {"Indexes", 3},
        new Object[] {"IndexColumns", 2},
        new Object[] {"ForeignKeys", 2},
        };
        DataTable dt = new DataTable(CUBRIDSchemaProvider.MetaCollectionName);
        dt.Columns.Add(new DataColumn("CollectionName", typeof(string)));
        dt.Columns.Add(new DataColumn("NumberOfRestrictions", typeof(int)));
        for (int i = 0; i < collections.Length; i++) { DataRow row = dt.NewRow(); row[0] = collections[i][0]; row[1] = collections[i][1]; dt.Rows.Add(row); }
        return dt;
        }{code}
        Show
        cn16359 唐勤 added a comment - Improve the implementation of CUBRIDConnection.GetSchema() Change it to return the meta data of supported collection names. 1. In CUBRIDConnection.cs {code} public override DataTable GetSchema() { return GetSchema(CUBRIDSchemaProvider.MetaCollectionName); }{code} 2. In CUBRIDSchemaProvider.cs {code} private static DataTable GetMetaDataCollections() { object[][] collections = new object[][] { new object[] {CUBRIDSchemaProvider.MetaCollectionName, 0}, new Object[] {"ReservedWords", 0}, new Object[] {"Users",1}, new Object[] {"Databases", 1}, new Object[] {"Procedures", 1}, new Object[] {"Tables", 1}, new Object[] {"Views", 1}, new Object[] {"Columns", 2}, new Object[] {"Indexes", 3}, new Object[] {"IndexColumns", 2}, new Object[] {"ForeignKeys", 2}, }; DataTable dt = new DataTable(CUBRIDSchemaProvider.MetaCollectionName); dt.Columns.Add(new DataColumn("CollectionName", typeof(string))); dt.Columns.Add(new DataColumn("NumberOfRestrictions", typeof(int))); for (int i = 0; i < collections.Length; i++) { DataRow row = dt.NewRow(); row[0] = collections[i][0]; row[1] = collections[i][1]; dt.Rows.Add(row); } return dt; }{code}
        Hide
        cn16359 唐勤 added a comment -

        Add support of CUBRIDConnection.GetSchema() to return the meta data of supported collection names.

        Show
        cn16359 唐勤 added a comment - Add support of CUBRIDConnection.GetSchema() to return the meta data of supported collection names.
        Hide
        ryin005 Ray Yin added a comment -

        Add a case for this issue

        RB-9.3.0

        {code}
        [TestMethod]
        public void APIS_728()
        {
        CUBRIDConnection conn = new CUBRIDConnection();
        conn.ConnectionString = "server=localhost;database=demodb;port=33000;user=dba;password=";

        try
        { DataTable dt = conn.GetSchema("TABLES"); }
        catch (Exception e)
        { Assert.AreEqual("The connection is not open!", e.Message); }

        conn.Open();
        DataTable dt_test = conn.GetSchema("TABLES");
        Assert.IsNotNull(dt_test);
        dt_test = conn.GetSchema("ReservedWords");
        Assert.IsNotNull(dt_test);
        dt_test = conn.GetSchema("Users");
        Assert.IsNotNull(dt_test);
        dt_test = conn.GetSchema("Databases");
        Assert.IsNotNull(dt_test);
        dt_test = conn.GetSchema("Views");
        Assert.IsNotNull(dt_test);
        dt_test = conn.GetSchema("Columns", new String[] { "game", "event_code" });
        Assert.IsNotNull(dt_test);
        dt_test = conn.GetSchema("Indexes", new String[] { "nation", "code" });
        Assert.IsNotNull(dt_test);
        dt_test = conn.GetSchema("Index_Columns", new String[] { "nation", "pk_nation_code" });
        Assert.IsNotNull(dt_test);
        dt_test = conn.GetSchema("FOREIGN_KEYS", new String[] { "game", "fk_game_athlete_code" });
        Assert.IsNotNull(dt_test);

        dt_test = conn.GetSchema("INVALID");
        Assert.IsNull(dt_test);

        conn.Close();
        }{code}

        Link: http://svn.bds.nhncorp.com/xdbms/cubridqa/branches/RB-9.3.0/interface/ADO.NET/unit_test/ADOTest/ADOTest/BTS_issue.cs

        Show
        ryin005 Ray Yin added a comment - Add a case for this issue RB-9.3.0 {code} [TestMethod] public void APIS_728() { CUBRIDConnection conn = new CUBRIDConnection(); conn.ConnectionString = "server=localhost;database=demodb;port=33000;user=dba;password="; try { DataTable dt = conn.GetSchema("TABLES"); } catch (Exception e) { Assert.AreEqual("The connection is not open!", e.Message); } conn.Open(); DataTable dt_test = conn.GetSchema("TABLES"); Assert.IsNotNull(dt_test); dt_test = conn.GetSchema("ReservedWords"); Assert.IsNotNull(dt_test); dt_test = conn.GetSchema("Users"); Assert.IsNotNull(dt_test); dt_test = conn.GetSchema("Databases"); Assert.IsNotNull(dt_test); dt_test = conn.GetSchema("Views"); Assert.IsNotNull(dt_test); dt_test = conn.GetSchema("Columns", new String[] { "game", "event_code" }); Assert.IsNotNull(dt_test); dt_test = conn.GetSchema("Indexes", new String[] { "nation", "code" }); Assert.IsNotNull(dt_test); dt_test = conn.GetSchema("Index_Columns", new String[] { "nation", "pk_nation_code" }); Assert.IsNotNull(dt_test); dt_test = conn.GetSchema("FOREIGN_KEYS", new String[] { "game", "fk_game_athlete_code" }); Assert.IsNotNull(dt_test); dt_test = conn.GetSchema("INVALID"); Assert.IsNull(dt_test); conn.Close(); }{code} Link: http://svn.bds.nhncorp.com/xdbms/cubridqa/branches/RB-9.3.0/interface/ADO.NET/unit_test/ADOTest/ADOTest/BTS_issue.cs
        Hide
        ryin005 Ray Yin added a comment -

        Test Build: 9.3.0.0165
        Test OS: Windows 32bit
        .NET: 4.0
        Driver: cubrid-ado.net 9.3.0.0001(20140409)

        Test Result: Pass

        Close the issue

        Show
        ryin005 Ray Yin added a comment - Test Build: 9.3.0.0165 Test OS: Windows 32bit .NET: 4.0 Driver: cubrid-ado.net 9.3.0.0001(20140409) Test Result: Pass Close the issue

          People

          • Assignee:
            cn16359 唐勤
            Reporter:
            ryin005 Ray Yin
            CC (Referrer):
            Esen Sagynov, Isaiah Choe, 唐勤, 户向伟, 范再强, 谢韦华[Bert]
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: