⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctable.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
字号:
/***************************************************************************  CTable.c  The Table, Field and Index class  (c) 2000-2003 Beno顃 Minisini <gambas@users.sourceforge.net>  This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 1, or (at your option)  any later version.  This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#define __CTABLE_C#include <ctype.h>#include "main.h"#include "CField.h"#include "CIndex.h"#include "CTable.h"static GB_SUBCOLLECTION_DESC _fields_desc = {  ".TableFields",  (void *)CFIELD_get,  (void *)CFIELD_exist,  (void *)CFIELD_list};static GB_SUBCOLLECTION_DESC _indexes_desc = {  ".TableIndexes",  (void *)CINDEX_get,  (void *)CINDEX_exist,  (void *)CINDEX_list};static int valid_table(CTABLE *_object){  return (THIS->conn->handle == NULL);}static bool check_table(CCONNECTION *conn, char *name, bool must_exist){  bool exist = conn->driver->Table.Exist(conn->handle, name, conn->desc.version);  if (must_exist)  {    if (!exist)    {      GB.Error("Unknown table: &1", name);      return TRUE;    }  }  else  {    if (exist)    {      GB.Error("Table already exists: &1", name);      return TRUE;    }  }  return FALSE;}static CTABLE *make_table(CCONNECTION *conn, const char *name, bool must_exist){  CTABLE *_object;    if (check_table(conn, (char *)name, must_exist))    return NULL;    GB.New((void **)&_object, GB.FindClass("Table"), NULL, NULL);  THIS->conn = conn;  GB.Ref(conn);  THIS->driver = conn->driver;  GB.NewString(&THIS->name, name, 0);  return _object;}void *CTABLE_get(CCONNECTION *conn, const char *name){  return make_table(conn, name, TRUE);}int CTABLE_exist(CCONNECTION *conn, const char *name){  return conn->driver->Table.Exist(conn->handle, (char *)name, conn->desc.version);}void CTABLE_list(CCONNECTION *conn, char ***list){  conn->driver->Table.List(conn->handle, list, conn->desc.version);}/***************************************************************************  Table***************************************************************************/static void free_new_fields(CTABLE *_object){  DB_FIELD *fp;  DB_FIELD *next;  for (fp = THIS->new_fields; fp; fp = next)  {    next = fp->next;    CFIELD_free_info(fp);    GB.Free((void **)&fp);  }  THIS->new_fields = NULL;}BEGIN_PROPERTY(CTABLE_primary_key)  GB_ARRAY primary;  int i, n;  char *field;  if (THIS->create)  {    if (READ_PROPERTY)    {      if (!THIS->primary)      {        GB.ReturnNull();        return;      }      GB.ReturnObject(DB_StringArrayToGambasArray(THIS->primary));    }    else    {      primary = (GB_ARRAY)VPROP(GB_OBJECT);      if (primary)        n = GB.Array.Count(primary);      else        n = 0;      for (i = 0; i < n; i++)      {        field = *((char **)GB.Array.Get(primary, i));        if (!CFIELD_exist(THIS, field))        {          GB.Error("Unknown field: &1", field);          return;        }      }            DB_FreeStringArray(&THIS->primary);      if (n)      {        GB.NewArray(&THIS->primary, sizeof(char *), n);        for (i = 0; i < n; i++)          GB.NewString(&THIS->primary[i], *((char **)GB.Array.Get(primary, i)), 0);      }    }  }  else  {    if (READ_PROPERTY)    {      if (THIS->driver->Table.PrimaryKey(THIS->conn->handle, THIS->name, &THIS->primary))        return;      GB.ReturnObject(DB_StringArrayToGambasArray(THIS->primary));      DB_FreeStringArray(&THIS->primary);    }    else      GB.Error("Read-only property");  }END_PROPERTYBEGIN_PROPERTY(CTABLE_name)  GB.ReturnString(THIS->name);END_PROPERTYBEGIN_PROPERTY(CTABLE_system)  GB.ReturnBoolean(THIS->driver->Table.IsSystem(THIS->conn->handle, THIS->name, THIS->conn->desc.version));END_PROPERTYBEGIN_PROPERTY(CTABLE_type)  if (THIS->create)  {    if (READ_PROPERTY)      GB.ReturnString(THIS->type);    else      GB.StoreString(PROP(GB_STRING), &THIS->type);  }  else   {    if (READ_PROPERTY)      GB.ReturnNewZeroString(THIS->driver->Table.Type(THIS->conn->handle, THIS->name, NULL));    else       THIS->driver->Table.Type(THIS->conn->handle, THIS->name, GB.ToZeroString(PROP(GB_STRING)));  }END_PROPERTYBEGIN_METHOD_VOID(CTABLE_update)  if (!THIS->new_fields)  {    GB.Error("No field");    return;  }  /*if (!THIS->primary || GB.Count(THIS->primary) == 0)  {    GB.Error("No primary key");    return;  }*/  if (THIS->driver->Table.Create(THIS->conn->handle, THIS->name, THIS->new_fields, THIS->primary, THIS->type))    return;  free_new_fields(THIS);  DB_FreeStringArray(&THIS->primary);  THIS->create = FALSE;    //GB.Unref(THIS);END_METHODBEGIN_METHOD_VOID(CTABLE_free)  if (!valid_table(THIS))    GB.SubCollection.Remove(THIS->conn->tables, THIS->name, 0);  GB.Unref((void **)&THIS->conn);  GB.FreeString(&THIS->name);  GB.FreeString(&THIS->type);  DB_FreeStringArray(&THIS->primary);  free_new_fields(THIS);END_METHODBEGIN_PROPERTY(CTABLE_fields)  GB.SubCollection.New(&THIS->fields, &_fields_desc, THIS);  GB.ReturnObject(THIS->fields);  END_PROPERTYBEGIN_PROPERTY(CTABLE_indexes)  GB.SubCollection.New(&THIS->indexes, &_indexes_desc, THIS);    GB.ReturnObject(THIS->indexes);END_PROPERTYBEGIN_PROPERTY(CTABLE_connection)  GB.ReturnObject(THIS->conn);END_PROPERTYGB_DESC CTableDesc[] ={  GB_DECLARE("Table", sizeof(CTABLE)),   GB_NOT_CREATABLE(),  GB_HOOK_CHECK(valid_table),  GB_METHOD("_free", NULL, CTABLE_free, NULL),  //GB_METHOD("AddField", NULL, CTABLE_add_field, "(Name)s(Type)i[(Length)i(Default)v"])  GB_PROPERTY_READ("Name", "s", CTABLE_name),  GB_PROPERTY_READ("System", "b", CTABLE_system),  GB_PROPERTY("PrimaryKey", "String[]", CTABLE_primary_key),  GB_PROPERTY("Type", "s", CTABLE_type),  GB_PROPERTY_READ("Connection", "Connection", CTABLE_connection),  GB_METHOD("Update", NULL, CTABLE_update, NULL),  GB_PROPERTY_READ("Fields", ".TableFields", CTABLE_fields),  GB_PROPERTY_READ("Indexes", ".TableIndexes", CTABLE_indexes),  GB_END_DECLARE};/***************************************************************************  .ConnectionTables***************************************************************************/#undef THIS#define THIS ((GB_SUBCOLLECTION)_object)BEGIN_METHOD(CTABLE_add, GB_STRING name; GB_STRING type)  CCONNECTION *conn = GB.SubCollection.Container(THIS);  CTABLE *table;  char *name = GB.ToZeroString(ARG(name));    if (DB_CheckName(name, "table"))    return;  table = make_table(conn, name, FALSE);  if (!table)    return;    GB.SubCollection.Add(THIS, STRING(name), LENGTH(name), table);  //GB.Ref(table);    if (!MISSING(type))    GB.StoreString(ARG(type), &table->type);  table->create = TRUE;  GB.ReturnObject(table);END_METHODBEGIN_METHOD(CTABLE_remove, GB_STRING name)  CCONNECTION *conn = GB.SubCollection.Container(THIS);  char *name = GB.ToZeroString(ARG(name));  if (check_table(conn, name, TRUE))    return;  GB.SubCollection.Remove(THIS, STRING(name), LENGTH(name));  conn->driver->Table.Delete(conn->handle, name);END_METHODGB_DESC CConnectionTablesDesc[] ={  GB_DECLARE(".ConnectionTables", 0), GB_INHERITS(".SubCollection"),  GB_METHOD("Add", "Table", CTABLE_add, "(Name)s[(Type)s]"),  GB_METHOD("Remove", NULL, CTABLE_remove, "(Name)s"),    //GB_METHOD("Refresh", NULL, CTABLE_refresh, NULL),  //GB_METHOD("Delete", NULL, CTABLE_delete, "(Name)s"),  //GB_METHOD("Exist", "b", CTABLE_exist, "(Name)s"),  GB_END_DECLARE};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -